Sync progress merged
- the progress is merged now but boolean value whether funds are spendable or not has been added extra
This commit is contained in:
parent
f56fde9cb9
commit
e2956a190e
|
@ -21,14 +21,18 @@ enum DemoAppConfig {
|
|||
static let host = ZcashSDK.isMainnet ? "zec.rocks" : "lightwalletd.testnet.electriccoin.co"
|
||||
static let port: Int = 443
|
||||
|
||||
static let defaultBirthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 935000 : 1386000
|
||||
static let defaultBirthdayHeight: BlockHeight = 2832500//ZcashSDK.isMainnet ? 935000 : 1386000
|
||||
|
||||
// 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 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: """
|
||||
live combine flight accident slow soda mind bright absent bid hen shy decade biology amazing mix enlist ensure biology rhythm snap duty soap armor
|
||||
wreck craft number between hard warfare wisdom leave radar host local crane float play logic whale clap parade dynamic cotton attitude people guard together
|
||||
""")
|
||||
|
||||
static let otherSynchronizers: [SynchronizerInitData] = [
|
||||
|
|
|
@ -319,8 +319,8 @@ extension SendViewController: UITextViewDelegate {
|
|||
extension SDKSynchronizer {
|
||||
static func textFor(state: SyncStatus) -> String {
|
||||
switch state {
|
||||
case let .syncing(syncProgress, recoveryProgress):
|
||||
return "Syncing \(syncProgress * 100.0)% \((recoveryProgress ?? 0) * 100.0)%"
|
||||
case let .syncing(syncProgress, areFundsSpendable):
|
||||
return "Syncing \(syncProgress * 100.0)% spendable: \(areFundsSpendable)"
|
||||
|
||||
case .upToDate:
|
||||
return "Up to Date 😎"
|
||||
|
|
|
@ -172,8 +172,8 @@ extension SyncBlocksListViewController: UITableViewDataSource {
|
|||
extension SyncStatus {
|
||||
var text: String {
|
||||
switch self {
|
||||
case let .syncing(syncProgress, recoveryProgress):
|
||||
return "Syncing 🤖 \(floor(syncProgress * 1000) / 10)% \(floor((recoveryProgress ?? 0) * 1000) / 10)%"
|
||||
case let .syncing(syncProgress, areFundsSpendable):
|
||||
return "Syncing 🤖 \(floor(syncProgress * 1000) / 10)% spendable: \(areFundsSpendable)"
|
||||
case .upToDate:
|
||||
return "Up to Date 😎"
|
||||
case .unprepared:
|
||||
|
|
|
@ -68,11 +68,13 @@ class SyncBlocksViewController: UIViewController {
|
|||
case .unprepared:
|
||||
break
|
||||
|
||||
case let .syncing(syncProgress, recoveryProgress):
|
||||
case let .syncing(syncProgress, areFundsSpendable):
|
||||
enhancingStarted = false
|
||||
|
||||
print("__LD syncProgress \(syncProgress) areFundsSpendable \(areFundsSpendable)")
|
||||
|
||||
progressBar.progress = syncProgress
|
||||
progressLabel.text = "\(floor(syncProgress * 1000) / 10)% \(floor((recoveryProgress ?? 0) * 1000) / 10)%"
|
||||
progressLabel.text = "\(floor(syncProgress * 1000) / 10)% spendable: \(areFundsSpendable)"
|
||||
let progressText = """
|
||||
latest block height \(state.latestBlockHeight)
|
||||
"""
|
||||
|
|
|
@ -74,14 +74,32 @@ extension ScanAction: Action {
|
|||
// TODO: [#1353] Advanced progress reporting, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1353
|
||||
if progressReportReducer == 0 {
|
||||
let walletSummary = try? await rustBackend.getWalletSummary()
|
||||
let recoveryProgress = try? walletSummary?.recoveryProgress?.progress()
|
||||
let recoveryProgress = walletSummary?.recoveryProgress
|
||||
|
||||
// report scan progress only if it's available
|
||||
if let scanProgress = walletSummary?.scanProgress {
|
||||
logger.debug("progress ratio: \(scanProgress.numerator)/\(scanProgress.denominator)")
|
||||
let progress = try scanProgress.progress()
|
||||
logger.debug("progress float: \(progress) \(String(describing: recoveryProgress))")
|
||||
await didUpdate(.syncProgress(progress, recoveryProgress))
|
||||
let composedNumerator: Float = Float(scanProgress.numerator) + Float(recoveryProgress?.numerator ?? 0)
|
||||
let composedDenominator: Float = Float(scanProgress.denominator) + Float(recoveryProgress?.denominator ?? 0)
|
||||
|
||||
logger.debug("progress ratio: \(composedNumerator)/\(composedDenominator)")
|
||||
|
||||
let progress: Float
|
||||
if composedDenominator == 0 {
|
||||
progress = 1.0
|
||||
} else {
|
||||
progress = composedNumerator / composedDenominator
|
||||
}
|
||||
|
||||
// this shouldn't happen but if it does, we need to get notified by clients and work on a fix
|
||||
if progress > 1.0 {
|
||||
throw ZcashError.rustScanProgressOutOfRange("\(progress)")
|
||||
}
|
||||
|
||||
let scanProgress: Float = (try? scanProgress.progress()) ?? 0.0
|
||||
let areFundsSpendable = scanProgress == 1.0
|
||||
|
||||
logger.debug("progress float: \(progress)")
|
||||
await didUpdate(.syncProgress(progress, areFundsSpendable))
|
||||
}
|
||||
|
||||
progressReportReducer = Constants.reportDelay
|
||||
|
|
|
@ -483,10 +483,10 @@ extension CompactBlockProcessor {
|
|||
case handledReorg(_ reorgHeight: BlockHeight, _ rewindHeight: BlockHeight)
|
||||
|
||||
/// Event sent when progress of some specific action happened.
|
||||
case syncProgress(Float, Float?)
|
||||
case syncProgress(Float, Bool)
|
||||
|
||||
/// Event sent when progress of the sync process changes.
|
||||
case progressUpdated(Float, Float?)
|
||||
case progressUpdated(Float, Bool)
|
||||
|
||||
/// Event sent when the CompactBlockProcessor fetched utxos from lightwalletd attempted to store them.
|
||||
case storedUTXOs((inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]))
|
||||
|
@ -568,9 +568,9 @@ extension CompactBlockProcessor {
|
|||
context = try await action.run(with: context) { [weak self] event in
|
||||
await self?.send(event: event)
|
||||
if let progressChanged = await self?.compactBlockProgress.hasProgressUpdated(event), progressChanged {
|
||||
if let progress = await self?.compactBlockProgress.syncProgress {
|
||||
if let progress = await self?.compactBlockProgress.progress {
|
||||
await self?.send(
|
||||
event: .progressUpdated(progress, self?.compactBlockProgress.recoveryProgress)
|
||||
event: .progressUpdated(progress, self?.compactBlockProgress.areFundsSpendable ?? false)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -715,7 +715,7 @@ extension CompactBlockProcessor {
|
|||
let lastScannedHeight = await latestBlocksDataProvider.maxScannedHeight
|
||||
// Some actions may not run. For example there are no transactions to enhance and therefore there is no enhance progress. And in
|
||||
// cases like this computation of final progress won't work properly. So let's fake 100% progress at the end of the sync process.
|
||||
await send(event: .progressUpdated(1, 1))
|
||||
await send(event: .progressUpdated(1, false))
|
||||
await send(event: .finished(lastScannedHeight))
|
||||
await context.update(state: .finished)
|
||||
|
||||
|
|
|
@ -10,16 +10,16 @@ import Foundation
|
|||
final actor CompactBlockProgress {
|
||||
static let zero = CompactBlockProgress()
|
||||
|
||||
var syncProgress: Float = 0.0
|
||||
var recoveryProgress: Float?
|
||||
var progress: Float = 0.0
|
||||
var areFundsSpendable: Bool = false
|
||||
|
||||
func hasProgressUpdated(_ event: CompactBlockProcessor.Event) -> Bool {
|
||||
guard case let .syncProgress(syncProgress, recoveryProgress) = event else {
|
||||
guard case let .syncProgress(progress, areFundsSpendable) = event else {
|
||||
return false
|
||||
}
|
||||
|
||||
self.syncProgress = syncProgress
|
||||
self.recoveryProgress = recoveryProgress
|
||||
self.progress = progress
|
||||
self.areFundsSpendable = areFundsSpendable
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -449,7 +449,7 @@ public enum SyncStatus: Equatable {
|
|||
/// taking other maintenance steps that need to occur after an upgrade.
|
||||
case unprepared
|
||||
|
||||
case syncing(_ syncProgress: Float, _ recoveryProgress: Float?)
|
||||
case syncing(_ syncProgress: Float, _ areFundsSpendable: Bool)
|
||||
|
||||
/// Indicates that this Synchronizer is fully up to date and ready for all wallet functions.
|
||||
/// When set, a UI element may want to turn green.
|
||||
|
@ -502,7 +502,7 @@ enum InternalSyncStatus: Equatable {
|
|||
case unprepared
|
||||
|
||||
/// Indicates that this Synchronizer is actively processing new blocks (consists of fetch, scan and enhance operations)
|
||||
case syncing(Float, Float?)
|
||||
case syncing(Float, Bool)
|
||||
|
||||
/// Indicates that this Synchronizer is fully up to date and ready for all wallet functions.
|
||||
/// When set, a UI element may want to turn green.
|
||||
|
@ -610,8 +610,8 @@ extension InternalSyncStatus {
|
|||
}
|
||||
|
||||
extension InternalSyncStatus {
|
||||
init(_ syncProgress: Float, _ recoveryProgress: Float?) {
|
||||
self = .syncing(syncProgress, recoveryProgress)
|
||||
init(_ syncProgress: Float, _ areFundsSpendable: Bool) {
|
||||
self = .syncing(syncProgress, areFundsSpendable)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -620,8 +620,8 @@ extension InternalSyncStatus {
|
|||
switch self {
|
||||
case .unprepared:
|
||||
return .unprepared
|
||||
case let .syncing(syncProgress, recoveryProgress):
|
||||
return .syncing(syncProgress, recoveryProgress)
|
||||
case let .syncing(syncProgress, areFundsSpendable):
|
||||
return .syncing(syncProgress, areFundsSpendable)
|
||||
case .synced:
|
||||
return .upToDate
|
||||
case .stopped:
|
||||
|
|
|
@ -174,9 +174,33 @@ public class SDKSynchronizer: Synchronizer {
|
|||
|
||||
case .stopped, .synced, .disconnected, .error:
|
||||
let walletSummary = try? await initializer.rustBackend.getWalletSummary()
|
||||
let recoveryProgress: Float? = try? walletSummary?.recoveryProgress?.progress()
|
||||
let syncProgress = (try? walletSummary?.scanProgress?.progress()) ?? 0
|
||||
await updateStatus(.syncing(syncProgress, recoveryProgress))
|
||||
let recoveryProgress = walletSummary?.recoveryProgress
|
||||
|
||||
var syncProgress: Float = 0.0
|
||||
var areFundsSpendable = false
|
||||
|
||||
if let scanProgress = walletSummary?.scanProgress {
|
||||
let composedNumerator: Float = Float(scanProgress.numerator) + Float(recoveryProgress?.numerator ?? 0)
|
||||
let composedDenominator: Float = Float(scanProgress.denominator) + Float(recoveryProgress?.denominator ?? 0)
|
||||
|
||||
let progress: Float
|
||||
if composedDenominator == 0 {
|
||||
progress = 1.0
|
||||
} else {
|
||||
progress = composedNumerator / composedDenominator
|
||||
}
|
||||
|
||||
// this shouldn't happen but if it does, we need to get notified by clients and work on a fix
|
||||
if progress > 1.0 {
|
||||
throw ZcashError.rustScanProgressOutOfRange("\(progress)")
|
||||
}
|
||||
|
||||
let scanProgress: Float = (try? scanProgress.progress()) ?? 0.0
|
||||
areFundsSpendable = scanProgress == 1.0
|
||||
|
||||
syncProgress = progress
|
||||
}
|
||||
await updateStatus(.syncing(syncProgress, areFundsSpendable))
|
||||
await blockProcessor.start(retry: retry)
|
||||
}
|
||||
}
|
||||
|
@ -242,8 +266,8 @@ public class SDKSynchronizer: Synchronizer {
|
|||
// log reorg information
|
||||
self?.logger.info("handling reorg at: \(reorgHeight) with rewind height: \(rewindHeight)")
|
||||
|
||||
case let .progressUpdated(syncProgress, recoveryProgress):
|
||||
await self?.progressUpdated(syncProgress, recoveryProgress)
|
||||
case let .progressUpdated(syncProgress, areFundsSpendable):
|
||||
await self?.progressUpdated(syncProgress, areFundsSpendable)
|
||||
|
||||
case .syncProgress:
|
||||
break
|
||||
|
@ -283,8 +307,8 @@ public class SDKSynchronizer: Synchronizer {
|
|||
}
|
||||
}
|
||||
|
||||
private func progressUpdated(_ syncProgress: Float, _ recoveryProgress: Float?) async {
|
||||
let newStatus = InternalSyncStatus(syncProgress, recoveryProgress)
|
||||
private func progressUpdated(_ syncProgress: Float, _ areFundsSpendable: Bool) async {
|
||||
let newStatus = InternalSyncStatus(syncProgress, areFundsSpendable)
|
||||
await updateStatus(newStatus)
|
||||
}
|
||||
|
||||
|
|
|
@ -197,19 +197,19 @@ class SynchronizerDarksideTests: ZcashTestCase {
|
|||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(0, 0),
|
||||
internalSyncStatus: .syncing(0, false),
|
||||
latestBlockHeight: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(0.9, 0),
|
||||
internalSyncStatus: .syncing(0.9, false),
|
||||
latestBlockHeight: 663189
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(1.0, 0),
|
||||
internalSyncStatus: .syncing(1.0, false),
|
||||
latestBlockHeight: 663189
|
||||
),
|
||||
SynchronizerState(
|
||||
|
@ -269,19 +269,19 @@ class SynchronizerDarksideTests: ZcashTestCase {
|
|||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(0, 0),
|
||||
internalSyncStatus: .syncing(0, false),
|
||||
latestBlockHeight: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(0.9, 0),
|
||||
internalSyncStatus: .syncing(0.9, false),
|
||||
latestBlockHeight: 663189
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(1.0, 0),
|
||||
internalSyncStatus: .syncing(1.0, false),
|
||||
latestBlockHeight: 663189
|
||||
),
|
||||
SynchronizerState(
|
||||
|
@ -320,19 +320,19 @@ class SynchronizerDarksideTests: ZcashTestCase {
|
|||
SynchronizerState(
|
||||
syncSessionID: uuids[1],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(0, 0),
|
||||
internalSyncStatus: .syncing(0, false),
|
||||
latestBlockHeight: 663189
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[1],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(0.9, 0),
|
||||
internalSyncStatus: .syncing(0.9, false),
|
||||
latestBlockHeight: 663200
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[1],
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(1.0, 0),
|
||||
internalSyncStatus: .syncing(1.0, false),
|
||||
latestBlockHeight: 663200
|
||||
),
|
||||
SynchronizerState(
|
||||
|
|
|
@ -333,7 +333,7 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
}
|
||||
|
||||
func testIsNewSessionOnUnpreparedToValidTransition() {
|
||||
XCTAssertTrue(SessionTicker.live.isNewSyncSession(.unprepared, .syncing(0, 0)))
|
||||
XCTAssertTrue(SessionTicker.live.isNewSyncSession(.unprepared, .syncing(0, false)))
|
||||
}
|
||||
|
||||
func testIsNotNewSessionOnUnpreparedToStateThatWontSync() {
|
||||
|
@ -348,8 +348,8 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
func testIsNotNewSyncSessionOnSameSession() {
|
||||
XCTAssertFalse(
|
||||
SessionTicker.live.isNewSyncSession(
|
||||
.syncing(0.5, 0),
|
||||
.syncing(0.6, 0)
|
||||
.syncing(0.5, false),
|
||||
.syncing(0.6, false)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
XCTAssertTrue(
|
||||
SessionTicker.live.isNewSyncSession(
|
||||
.synced,
|
||||
.syncing(0.6, 0)
|
||||
.syncing(0.6, false)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
XCTAssertTrue(
|
||||
SessionTicker.live.isNewSyncSession(
|
||||
.disconnected,
|
||||
.syncing(0.6, 0)
|
||||
.syncing(0.6, false)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -376,14 +376,14 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
XCTAssertTrue(
|
||||
SessionTicker.live.isNewSyncSession(
|
||||
.stopped,
|
||||
.syncing(0.6, 0)
|
||||
.syncing(0.6, false)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func testInternalSyncStatusesDontDifferWhenOuterStatusIsTheSame() {
|
||||
XCTAssertFalse(InternalSyncStatus.disconnected.isDifferent(from: .disconnected))
|
||||
XCTAssertFalse(InternalSyncStatus.syncing(0, 0).isDifferent(from: .syncing(0, 0)))
|
||||
XCTAssertFalse(InternalSyncStatus.syncing(0, false).isDifferent(from: .syncing(0, false)))
|
||||
XCTAssertFalse(InternalSyncStatus.stopped.isDifferent(from: .stopped))
|
||||
XCTAssertFalse(InternalSyncStatus.synced.isDifferent(from: .synced))
|
||||
XCTAssertFalse(InternalSyncStatus.unprepared.isDifferent(from: .unprepared))
|
||||
|
@ -392,10 +392,10 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
func testInternalSyncStatusMap_SyncingLowerBound() {
|
||||
let synchronizerState = synchronizerState(
|
||||
for:
|
||||
InternalSyncStatus.syncing(0, 0)
|
||||
InternalSyncStatus.syncing(0, false)
|
||||
)
|
||||
|
||||
if case let .syncing(data, 0) = synchronizerState.syncStatus, data != nextafter(0.0, data) {
|
||||
if case let .syncing(data, false) = synchronizerState.syncStatus, data != nextafter(0.0, data) {
|
||||
XCTFail("Syncing is expected to be 0% (0.0) but received \(data).")
|
||||
}
|
||||
}
|
||||
|
@ -403,10 +403,10 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
func testInternalSyncStatusMap_SyncingInTheMiddle() {
|
||||
let synchronizerState = synchronizerState(
|
||||
for:
|
||||
InternalSyncStatus.syncing(0.45, 0)
|
||||
InternalSyncStatus.syncing(0.45, false)
|
||||
)
|
||||
|
||||
if case let .syncing(data, 0) = synchronizerState.syncStatus, data != nextafter(0.45, data) {
|
||||
if case let .syncing(data, false) = synchronizerState.syncStatus, data != nextafter(0.45, data) {
|
||||
XCTFail("Syncing is expected to be 45% (0.45) but received \(data).")
|
||||
}
|
||||
}
|
||||
|
@ -414,18 +414,18 @@ class SynchronizerOfflineTests: ZcashTestCase {
|
|||
func testInternalSyncStatusMap_SyncingUpperBound() {
|
||||
let synchronizerState = synchronizerState(
|
||||
for:
|
||||
InternalSyncStatus.syncing(0.9, 0)
|
||||
InternalSyncStatus.syncing(0.9, false)
|
||||
)
|
||||
|
||||
if case let .syncing(data, 0) = synchronizerState.syncStatus, data != nextafter(0.9, data) {
|
||||
if case let .syncing(data, false) = synchronizerState.syncStatus, data != nextafter(0.9, data) {
|
||||
XCTFail("Syncing is expected to be 90% (0.9) but received \(data).")
|
||||
}
|
||||
}
|
||||
|
||||
func testInternalSyncStatusMap_FetchingUpperBound() {
|
||||
let synchronizerState = synchronizerState(for: InternalSyncStatus.syncing(1, 0))
|
||||
let synchronizerState = synchronizerState(for: InternalSyncStatus.syncing(1, false))
|
||||
|
||||
if case let .syncing(data, 0) = synchronizerState.syncStatus, data != nextafter(1.0, data) {
|
||||
if case let .syncing(data, false) = synchronizerState.syncStatus, data != nextafter(1.0, data) {
|
||||
XCTFail("Syncing is expected to be 100% (1.0) but received \(data).")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ extension SynchronizerState {
|
|||
SynchronizerState(
|
||||
syncSessionID: .nullID,
|
||||
accountsBalances: [:],
|
||||
internalSyncStatus: .syncing(0, 0),
|
||||
internalSyncStatus: .syncing(0, false),
|
||||
latestBlockHeight: 222222
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue