Merge pull request #1199 from LukasKorba/1181-Correct-computation-of-progress-for-Spend-before-Sync
[#1181] Correct computation of progress for Spend before Sync
This commit is contained in:
commit
dbd5a1ad3f
|
@ -8,6 +8,13 @@ be able to write to this location after it creates this directory. It is suggest
|
||||||
a subdirectory of the `Documents` directory. If this information is stored in `Documents` then the
|
a subdirectory of the `Documents` directory. If this information is stored in `Documents` then the
|
||||||
system itself won't remove these data.
|
system itself won't remove these data.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
### [#1181] Correct computation of progress for Spend before Sync
|
||||||
|
`latestScannedHeight` and `latestScannedTime` have been removed from `SynchronizerState`. With multiple algorithms
|
||||||
|
of syncing the amount of data provided is reduced so it's consistent. Spend before Sync is done in non-linear order
|
||||||
|
so both Height and Time don't make sense anymore.
|
||||||
|
|
||||||
# 0.22.0-beta
|
# 0.22.0-beta
|
||||||
|
|
||||||
## Checkpoints
|
## Checkpoints
|
||||||
|
|
|
@ -18,7 +18,7 @@ enum DemoAppConfig {
|
||||||
let seed: [UInt8]
|
let seed: [UInt8]
|
||||||
}
|
}
|
||||||
|
|
||||||
static let host = ZcashSDK.isMainnet ? "mainnet.lightwalletd.com" : "testnet.lightwalletd.com"
|
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
|
||||||
|
|
|
@ -112,7 +112,6 @@ class SyncBlocksListViewController: UIViewController {
|
||||||
outputParamsURL: try! outputParamsURLHelper(),
|
outputParamsURL: try! outputParamsURLHelper(),
|
||||||
saplingParamsSourceURL: SaplingParamsSourceURL.default,
|
saplingParamsSourceURL: SaplingParamsSourceURL.default,
|
||||||
alias: data.alias,
|
alias: data.alias,
|
||||||
syncAlgorithm: .spendBeforeSync,
|
|
||||||
loggingPolicy: .default(.debug),
|
loggingPolicy: .default(.debug),
|
||||||
enableBackendTracing: true
|
enableBackendTracing: true
|
||||||
)
|
)
|
||||||
|
|
|
@ -84,10 +84,7 @@ class SyncBlocksViewController: UIViewController {
|
||||||
|
|
||||||
progressBar.progress = progress
|
progressBar.progress = progress
|
||||||
progressLabel.text = "\(floor(progress * 1000) / 10)%"
|
progressLabel.text = "\(floor(progress * 1000) / 10)%"
|
||||||
let syncedDate = dateFormatter.string(from: Date(timeIntervalSince1970: state.latestScannedTime))
|
|
||||||
let progressText = """
|
let progressText = """
|
||||||
synced date \(syncedDate)
|
|
||||||
synced block \(state.latestScannedHeight)
|
|
||||||
latest block height \(state.latestBlockHeight)
|
latest block height \(state.latestBlockHeight)
|
||||||
"""
|
"""
|
||||||
progressDataLabel.text = progressText
|
progressDataLabel.text = progressText
|
||||||
|
|
|
@ -14,7 +14,10 @@ actor ActionContext {
|
||||||
let preferredSyncAlgorithm: SyncAlgorithm
|
let preferredSyncAlgorithm: SyncAlgorithm
|
||||||
var supportedSyncAlgorithm: SyncAlgorithm?
|
var supportedSyncAlgorithm: SyncAlgorithm?
|
||||||
var requestedRewindHeight: BlockHeight?
|
var requestedRewindHeight: BlockHeight?
|
||||||
|
/// Represents the overall range of blocks that will be synced, `SyncAlgorithm` doesn't matter.
|
||||||
var totalProgressRange: CompactBlockRange = 0...0
|
var totalProgressRange: CompactBlockRange = 0...0
|
||||||
|
/// Amount of blocks that have been processed so far
|
||||||
|
var processedHeight: BlockHeight = 0
|
||||||
var lastScannedHeight: BlockHeight?
|
var lastScannedHeight: BlockHeight?
|
||||||
var lastDownloadedHeight: BlockHeight?
|
var lastDownloadedHeight: BlockHeight?
|
||||||
var lastEnhancedHeight: BlockHeight?
|
var lastEnhancedHeight: BlockHeight?
|
||||||
|
@ -30,7 +33,11 @@ actor ActionContext {
|
||||||
self.state = state
|
self.state = state
|
||||||
}
|
}
|
||||||
func update(syncControlData: SyncControlData) async { self.syncControlData = syncControlData }
|
func update(syncControlData: SyncControlData) async { self.syncControlData = syncControlData }
|
||||||
func update(totalProgressRange: CompactBlockRange) async { self.totalProgressRange = totalProgressRange }
|
func update(totalProgressRange: CompactBlockRange) async {
|
||||||
|
self.processedHeight = totalProgressRange.lowerBound
|
||||||
|
self.totalProgressRange = totalProgressRange
|
||||||
|
}
|
||||||
|
func update(processedHeight: BlockHeight) async { self.processedHeight = processedHeight }
|
||||||
func update(lastScannedHeight: BlockHeight) async { self.lastScannedHeight = lastScannedHeight }
|
func update(lastScannedHeight: BlockHeight) async { self.lastScannedHeight = lastScannedHeight }
|
||||||
func update(lastDownloadedHeight: BlockHeight) async { self.lastDownloadedHeight = lastDownloadedHeight }
|
func update(lastDownloadedHeight: BlockHeight) async { self.lastDownloadedHeight = lastDownloadedHeight }
|
||||||
func update(lastEnhancedHeight: BlockHeight?) async { self.lastEnhancedHeight = lastEnhancedHeight }
|
func update(lastEnhancedHeight: BlockHeight?) async { self.lastEnhancedHeight = lastEnhancedHeight }
|
||||||
|
|
|
@ -46,7 +46,21 @@ extension ProcessSuggestedScanRangesAction: Action {
|
||||||
await context.update(lastScannedHeight: lowerBound)
|
await context.update(lastScannedHeight: lowerBound)
|
||||||
await context.update(lastDownloadedHeight: lowerBound)
|
await context.update(lastDownloadedHeight: lowerBound)
|
||||||
await context.update(syncControlData: syncControlData)
|
await context.update(syncControlData: syncControlData)
|
||||||
await context.update(totalProgressRange: lowerBound...upperBound)
|
|
||||||
|
// the total progress range is computed only for the first time
|
||||||
|
// as a sum of all ranges
|
||||||
|
let totalProgressRange = await context.totalProgressRange
|
||||||
|
if totalProgressRange.lowerBound == 0 && totalProgressRange.upperBound == 0 {
|
||||||
|
var minHeight = Int.max
|
||||||
|
var maxHeight = 0
|
||||||
|
scanRanges.forEach { range in
|
||||||
|
if range.range.lowerBound < minHeight { minHeight = range.range.lowerBound }
|
||||||
|
if range.range.upperBound > maxHeight { maxHeight = range.range.upperBound }
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Setting the total range for Spend before Sync to \(minHeight...maxHeight).")
|
||||||
|
await context.update(totalProgressRange: minHeight...maxHeight)
|
||||||
|
}
|
||||||
|
|
||||||
// If there is a range of blocks that needs to be verified, it will always
|
// If there is a range of blocks that needs to be verified, it will always
|
||||||
// be returned as the first element of the vector of suggested ranges.
|
// be returned as the first element of the vector of suggested ranges.
|
||||||
|
|
|
@ -51,11 +51,20 @@ extension ScanAction: Action {
|
||||||
let totalProgressRange = await context.totalProgressRange
|
let totalProgressRange = await context.totalProgressRange
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await blockScanner.scanBlocks(at: batchRange, totalProgressRange: totalProgressRange) { [weak self] lastScannedHeight in
|
try await blockScanner.scanBlocks(at: batchRange, totalProgressRange: totalProgressRange) { [weak self] lastScannedHeight, increment in
|
||||||
|
let processedHeight = await context.processedHeight
|
||||||
|
let incrementedprocessedHeight = processedHeight + BlockHeight(increment)
|
||||||
|
await context.update(
|
||||||
|
processedHeight:
|
||||||
|
incrementedprocessedHeight < totalProgressRange.upperBound
|
||||||
|
? incrementedprocessedHeight
|
||||||
|
: totalProgressRange.upperBound
|
||||||
|
)
|
||||||
|
|
||||||
let progress = BlockProgress(
|
let progress = BlockProgress(
|
||||||
startHeight: totalProgressRange.lowerBound,
|
startHeight: totalProgressRange.lowerBound,
|
||||||
targetHeight: totalProgressRange.upperBound,
|
targetHeight: totalProgressRange.upperBound,
|
||||||
progressHeight: lastScannedHeight
|
progressHeight: incrementedprocessedHeight
|
||||||
)
|
)
|
||||||
self?.logger.debug("progress: \(progress)")
|
self?.logger.debug("progress: \(progress)")
|
||||||
await didUpdate(.progressPartialUpdate(.syncing(progress)))
|
await didUpdate(.progressPartialUpdate(.syncing(progress)))
|
||||||
|
|
|
@ -521,7 +521,7 @@ extension CompactBlockProcessor {
|
||||||
// Execute action.
|
// Execute action.
|
||||||
context = try await action.run(with: context) { [weak self] event in
|
context = try await action.run(with: context) { [weak self] event in
|
||||||
await self?.send(event: event)
|
await self?.send(event: event)
|
||||||
if let progressChanged = await self?.compactBlockProgress.event(event), progressChanged {
|
if let progressChanged = await self?.compactBlockProgress.hasProgressUpdated(event), progressChanged {
|
||||||
if let progress = await self?.compactBlockProgress.progress {
|
if let progress = await self?.compactBlockProgress.progress {
|
||||||
await self?.send(event: .progressUpdated(progress))
|
await self?.send(event: .progressUpdated(progress))
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ protocol BlockScanner {
|
||||||
func scanBlocks(
|
func scanBlocks(
|
||||||
at range: CompactBlockRange,
|
at range: CompactBlockRange,
|
||||||
totalProgressRange: CompactBlockRange,
|
totalProgressRange: CompactBlockRange,
|
||||||
didScan: @escaping (BlockHeight) async -> Void
|
didScan: @escaping (BlockHeight, UInt32) async -> Void
|
||||||
) async throws -> BlockHeight
|
) async throws -> BlockHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ extension BlockScannerImpl: BlockScanner {
|
||||||
func scanBlocks(
|
func scanBlocks(
|
||||||
at range: CompactBlockRange,
|
at range: CompactBlockRange,
|
||||||
totalProgressRange: CompactBlockRange,
|
totalProgressRange: CompactBlockRange,
|
||||||
didScan: @escaping (BlockHeight) async -> Void
|
didScan: @escaping (BlockHeight, UInt32) async -> Void
|
||||||
) async throws -> BlockHeight {
|
) async throws -> BlockHeight {
|
||||||
logger.debug("Going to scan blocks in range: \(range)")
|
logger.debug("Going to scan blocks in range: \(range)")
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
|
@ -69,7 +69,7 @@ extension BlockScannerImpl: BlockScanner {
|
||||||
|
|
||||||
scannedNewBlocks = previousScannedHeight != lastScannedHeight
|
scannedNewBlocks = previousScannedHeight != lastScannedHeight
|
||||||
if scannedNewBlocks {
|
if scannedNewBlocks {
|
||||||
await didScan(lastScannedHeight)
|
await didScan(lastScannedHeight, batchSize)
|
||||||
|
|
||||||
let progress = BlockProgress(
|
let progress = BlockProgress(
|
||||||
startHeight: totalProgressRange.lowerBound,
|
startHeight: totalProgressRange.lowerBound,
|
||||||
|
|
|
@ -19,7 +19,7 @@ final actor CompactBlockProgress {
|
||||||
switch self {
|
switch self {
|
||||||
case .enhance: return 0.08
|
case .enhance: return 0.08
|
||||||
case .fetch: return 0.02
|
case .fetch: return 0.02
|
||||||
case .scan: return 0.9
|
case .scan: return 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,18 +35,13 @@ final actor CompactBlockProgress {
|
||||||
return overallProgress
|
return overallProgress
|
||||||
}
|
}
|
||||||
|
|
||||||
func event(_ event: CompactBlockProcessor.Event) -> Bool {
|
func hasProgressUpdated(_ event: CompactBlockProcessor.Event) -> Bool {
|
||||||
guard case .progressPartialUpdate(let update) = event else {
|
guard case .progressPartialUpdate(let update) = event else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
switch update {
|
if case let .syncing(progress) = update {
|
||||||
case .syncing(let progress):
|
|
||||||
actionProgresses[.scan] = progress.progress
|
actionProgresses[.scan] = progress.progress
|
||||||
case .enhance(let progress):
|
|
||||||
actionProgresses[.enhance] = progress.progress
|
|
||||||
case .fetch(let progress):
|
|
||||||
actionProgresses[.fetch] = progress
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -42,13 +42,8 @@ public struct SynchronizerState: Equatable {
|
||||||
/// status of the whole sync process
|
/// status of the whole sync process
|
||||||
var internalSyncStatus: InternalSyncStatus
|
var internalSyncStatus: InternalSyncStatus
|
||||||
public var syncStatus: SyncStatus
|
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.
|
/// height of the latest block on the blockchain known to this synchronizer.
|
||||||
public var latestBlockHeight: BlockHeight
|
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
|
/// Represents a synchronizer that has made zero progress hasn't done a sync attempt
|
||||||
public static var zero: SynchronizerState {
|
public static var zero: SynchronizerState {
|
||||||
|
@ -76,9 +71,7 @@ public struct SynchronizerState: Equatable {
|
||||||
self.shieldedBalance = shieldedBalance
|
self.shieldedBalance = shieldedBalance
|
||||||
self.transparentBalance = transparentBalance
|
self.transparentBalance = transparentBalance
|
||||||
self.internalSyncStatus = internalSyncStatus
|
self.internalSyncStatus = internalSyncStatus
|
||||||
self.latestScannedHeight = latestScannedHeight
|
|
||||||
self.latestBlockHeight = latestBlockHeight
|
self.latestBlockHeight = latestBlockHeight
|
||||||
self.latestScannedTime = latestScannedTime
|
|
||||||
self.syncStatus = internalSyncStatus.mapToSyncStatus()
|
self.syncStatus = internalSyncStatus.mapToSyncStatus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func allPendingTransactions() async throws -> [ZcashTransaction.Overview] {
|
public func allPendingTransactions() async throws -> [ZcashTransaction.Overview] {
|
||||||
let latestScannedHeight = self.latestState.latestScannedHeight
|
let latestScannedHeight = try await transactionRepository.lastScannedHeight()
|
||||||
|
|
||||||
return try await transactionRepository.findPendingTransactions(latestHeight: latestScannedHeight, offset: 0, limit: .max)
|
return try await transactionRepository.findPendingTransactions(latestHeight: latestScannedHeight, offset: 0, limit: .max)
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,11 +361,11 @@ class BlockScannerMock: BlockScanner {
|
||||||
var scanBlocksAtTotalProgressRangeDidScanCalled: Bool {
|
var scanBlocksAtTotalProgressRangeDidScanCalled: Bool {
|
||||||
return scanBlocksAtTotalProgressRangeDidScanCallsCount > 0
|
return scanBlocksAtTotalProgressRangeDidScanCallsCount > 0
|
||||||
}
|
}
|
||||||
var scanBlocksAtTotalProgressRangeDidScanReceivedArguments: (range: CompactBlockRange, totalProgressRange: CompactBlockRange, didScan: (BlockHeight) async -> Void)?
|
var scanBlocksAtTotalProgressRangeDidScanReceivedArguments: (range: CompactBlockRange, totalProgressRange: CompactBlockRange, didScan: (BlockHeight, UInt32) async -> Void)?
|
||||||
var scanBlocksAtTotalProgressRangeDidScanReturnValue: BlockHeight!
|
var scanBlocksAtTotalProgressRangeDidScanReturnValue: BlockHeight!
|
||||||
var scanBlocksAtTotalProgressRangeDidScanClosure: ((CompactBlockRange, CompactBlockRange, @escaping (BlockHeight) async -> Void) async throws -> BlockHeight)?
|
var scanBlocksAtTotalProgressRangeDidScanClosure: ((CompactBlockRange, CompactBlockRange, @escaping (BlockHeight, UInt32) async -> Void) async throws -> BlockHeight)?
|
||||||
|
|
||||||
func scanBlocks(at range: CompactBlockRange, totalProgressRange: CompactBlockRange, didScan: @escaping (BlockHeight) async -> Void) async throws -> BlockHeight {
|
func scanBlocks(at range: CompactBlockRange, totalProgressRange: CompactBlockRange, didScan: @escaping (BlockHeight, UInt32) async -> Void) async throws -> BlockHeight {
|
||||||
if let error = scanBlocksAtTotalProgressRangeDidScanThrowableError {
|
if let error = scanBlocksAtTotalProgressRangeDidScanThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue