Addressed comments batch 2

- more comments resolved
- totalProgressRange removed from the SDK
- ScanRange now takes into account the given value and properly initializes, + added tests
- tests fixed
This commit is contained in:
Lukas Korba 2023-09-13 17:33:37 +02:00
parent 5600e77a71
commit 4e2af5da68
9 changed files with 52 additions and 167 deletions

View File

@ -29,7 +29,6 @@ class SyncBlocksViewController: UIViewController {
guard let currentMetric else { return "" }
switch currentMetric {
case .downloadBlocks: return "download: "
case .validateBlocks: return "validate: "
case .scanBlocks: return "scan: "
case .enhancement: return "enhancement: "
case .fetchUTXOs: return "fetchUTXOs: "
@ -117,7 +116,6 @@ class SyncBlocksViewController: UIViewController {
let cumulativeSummary = synchronizer.metrics.cumulativeSummary()
let downloadedBlocksReport = cumulativeSummary.downloadedBlocksReport ?? SDKMetrics.ReportSummary.zero
let validatedBlocksReport = cumulativeSummary.validatedBlocksReport ?? SDKMetrics.ReportSummary.zero
let scannedBlocksReport = cumulativeSummary.scannedBlocksReport ?? SDKMetrics.ReportSummary.zero
let enhancementReport = cumulativeSummary.enhancementReport ?? SDKMetrics.ReportSummary.zero
let fetchUTXOsReport = cumulativeSummary.fetchUTXOsReport ?? SDKMetrics.ReportSummary.zero
@ -127,7 +125,6 @@ class SyncBlocksViewController: UIViewController {
"""
Summary:
downloadedBlocks: min: \(downloadedBlocksReport.minTime) max: \(downloadedBlocksReport.maxTime) avg: \(downloadedBlocksReport.avgTime)
validatedBlocks: min: \(validatedBlocksReport.minTime) max: \(validatedBlocksReport.maxTime) avg: \(validatedBlocksReport.avgTime)
scannedBlocks: min: \(scannedBlocksReport.minTime) max: \(scannedBlocksReport.maxTime) avg: \(scannedBlocksReport.avgTime)
enhancement: min: \(enhancementReport.minTime) max: \(enhancementReport.maxTime) avg: \(enhancementReport.avgTime)
fetchUTXOs: min: \(fetchUTXOsReport.minTime) max: \(fetchUTXOsReport.maxTime) avg: \(fetchUTXOsReport.avgTime)

View File

@ -12,7 +12,6 @@ protocol ActionContext {
var prevState: CBPState? { get async }
var syncControlData: SyncControlData { get async }
var requestedRewindHeight: BlockHeight? { get async }
var totalProgressRange: CompactBlockRange { get async }
var processedHeight: BlockHeight { get async }
var lastChainTipUpdateTime: TimeInterval { get async }
var lastScannedHeight: BlockHeight? { get async }
@ -20,7 +19,6 @@ protocol ActionContext {
func update(state: CBPState) async
func update(syncControlData: SyncControlData) async
func update(totalProgressRange: CompactBlockRange) async
func update(processedHeight: BlockHeight) async
func update(lastChainTipUpdateTime: TimeInterval) async
func update(lastScannedHeight: BlockHeight) async

View File

@ -47,21 +47,6 @@ extension ProcessSuggestedScanRangesAction: Action {
await context.update(lastDownloadedHeight: rangeStartExclusive)
await context.update(syncControlData: syncControlData)
// 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)
}
await context.update(state: .download)
} else {
await context.update(state: .finished)

View File

@ -48,18 +48,12 @@ extension ScanAction: Action {
let batchRange = batchRangeStart...batchRangeEnd
logger.debug("Starting scan blocks with range: \(batchRange.lowerBound)...\(batchRange.upperBound)")
let totalProgressRange = await context.totalProgressRange
do {
try await blockScanner.scanBlocks(at: batchRange, totalProgressRange: totalProgressRange) { [weak self] lastScannedHeight, increment in
try await blockScanner.scanBlocks(at: batchRange) { [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
)
await context.update(processedHeight: incrementedprocessedHeight)
// report scan progress only if it's available
if let scanProgress = try? await self?.rustBackend.getScanProgress() {

View File

@ -16,7 +16,6 @@ protocol BlockScanner {
@discardableResult
func scanBlocks(
at range: CompactBlockRange,
totalProgressRange: CompactBlockRange,
didScan: @escaping (BlockHeight, UInt32) async throws -> Void
) async throws -> BlockHeight
}
@ -33,7 +32,6 @@ extension BlockScannerImpl: BlockScanner {
@discardableResult
func scanBlocks(
at range: CompactBlockRange,
totalProgressRange: CompactBlockRange,
didScan: @escaping (BlockHeight, UInt32) async throws -> Void
) async throws -> BlockHeight {
logger.debug("Going to scan blocks in range: \(range)")

View File

@ -18,7 +18,19 @@ struct ScanRange {
case verify = 60
init(_ value: UInt8) {
self = Priority(rawValue: value) ?? .ignored
// the given priority matches the values
if let priority = Priority(rawValue: value) {
self = priority
} else {
// no match found, getting the one above the value
let valueNeeded = (value / 10) * 10 + 10
if let priority = Priority(rawValue: valueNeeded) {
self = priority
} else {
fatalError("The value \(value) is out of the range of priorities.")
}
}
}
}

View File

@ -51,89 +51,6 @@ final class ProcessSuggestedScanRangesActionTests: ZcashTestCase {
}
}
func testProcessSuggestedScanRangesAction_VerifyScanRangeSetTotalProgressRange() async throws {
let loggerMock = LoggerMock()
loggerMock.infoFileFunctionLineClosure = { _, _, _, _ in }
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
let tupple = setupAction(loggerMock)
await tupple.rustBackendMock.setSuggestScanRangesClosure({ [
ScanRange(range: 0..<10, priority: .verify)
] })
let processSuggestedScanRangesActionAction = tupple.action
do {
let context = ActionContextMock.default()
context.updateLastScannedHeightClosure = { _ in }
context.updateLastDownloadedHeightClosure = { _ in }
context.updateSyncControlDataClosure = { _ in }
context.underlyingTotalProgressRange = 0...0
context.updateTotalProgressRangeClosure = { _ in }
context.updateRequestedRewindHeightClosure = { _ in }
let nextContext = try await processSuggestedScanRangesActionAction.run(with: context) { _ in }
XCTAssertTrue(
loggerMock.debugFileFunctionLineCalled,
"logger.debug() is not expected to be called."
)
if let infoArguments = loggerMock.infoFileFunctionLineReceivedArguments {
XCTAssertTrue(infoArguments.message.contains("Setting the total range for Spend before Sync to"))
} else {
XCTFail("`infoArguments` unavailable.")
}
let acResult = nextContext.checkStateIs(.download)
XCTAssertTrue(acResult == .true, "Check of state failed with '\(acResult)'")
} catch {
XCTFail("testProcessSuggestedScanRangesAction_VerifyScanRangeSetTotalProgressRange is not expected to fail. \(error)")
}
}
func testProcessSuggestedScanRangesAction_VerifyScanRangeTotalProgressRangeSkipped() async throws {
let loggerMock = LoggerMock()
loggerMock.infoFileFunctionLineClosure = { _, _, _, _ in }
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
let tupple = setupAction(loggerMock)
await tupple.rustBackendMock.setSuggestScanRangesClosure({ [
ScanRange(range: 0..<10, priority: .verify)
] })
let processSuggestedScanRangesActionAction = tupple.action
do {
let context = ActionContextMock.default()
context.updateLastScannedHeightClosure = { _ in }
context.updateLastDownloadedHeightClosure = { _ in }
context.updateSyncControlDataClosure = { _ in }
context.underlyingTotalProgressRange = 1...1
context.updateRequestedRewindHeightClosure = { _ in }
let nextContext = try await processSuggestedScanRangesActionAction.run(with: context) { _ in }
XCTAssertTrue(
loggerMock.debugFileFunctionLineCalled,
"logger.debug() is not expected to be called."
)
if let infoArguments = loggerMock.infoFileFunctionLineReceivedArguments {
XCTAssertFalse(infoArguments.message.contains("Setting the total range for Spend before Sync to"))
} else {
XCTFail("`infoArguments` unavailable.")
}
let acResult = nextContext.checkStateIs(.download)
XCTAssertTrue(acResult == .true, "Check of state failed with '\(acResult)'")
} catch {
XCTFail("testProcessSuggestedScanRangesAction_VerifyScanRangeTotalProgressRangeSkipped is not expected to fail. \(error)")
}
}
func testProcessSuggestedScanRangesAction_ChainTipScanRange() async throws {
let loggerMock = LoggerMock()
@ -152,7 +69,6 @@ final class ProcessSuggestedScanRangesActionTests: ZcashTestCase {
context.updateLastScannedHeightClosure = { _ in }
context.updateLastDownloadedHeightClosure = { _ in }
context.updateSyncControlDataClosure = { _ in }
context.underlyingTotalProgressRange = 1...1
context.updateRequestedRewindHeightClosure = { _ in }
let nextContext = try await processSuggestedScanRangesActionAction.run(with: context) { _ in }
@ -222,4 +138,23 @@ final class ProcessSuggestedScanRangesActionTests: ZcashTestCase {
rustBackendMock: rustBackendMock
)
}
func testScanRangePriorities() {
// matching priorities
XCTAssertEqual(ScanRange.Priority(0), .ignored)
XCTAssertEqual(ScanRange.Priority(10), .scanned)
XCTAssertEqual(ScanRange.Priority(20), .historic)
XCTAssertEqual(ScanRange.Priority(30), .openAdjacent)
XCTAssertEqual(ScanRange.Priority(40), .foundNote)
XCTAssertEqual(ScanRange.Priority(50), .chainTip)
XCTAssertEqual(ScanRange.Priority(60), .verify)
// custom priorities
XCTAssertEqual(ScanRange.Priority(4), .scanned)
XCTAssertEqual(ScanRange.Priority(14), .historic)
XCTAssertEqual(ScanRange.Priority(24), .openAdjacent)
XCTAssertEqual(ScanRange.Priority(34), .foundNote)
XCTAssertEqual(ScanRange.Priority(44), .chainTip)
XCTAssertEqual(ScanRange.Priority(54), .verify)
}
}

View File

@ -15,18 +15,17 @@ final class ScanActionTests: ZcashTestCase {
let loggerMock = LoggerMock()
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
blockScannerMock.scanBlocksAtTotalProgressRangeDidScanClosure = { _, _, _ in 2 }
let scanAction = setupAction(blockScannerMock, loggerMock)
let syncContext = ActionContextMock.default()
syncContext.lastScannedHeight = 1500
syncContext.underlyingTotalProgressRange = 1000...2000
syncContext.underlyingSyncControlData = SyncControlData(
latestBlockHeight: 2000,
latestScannedHeight: 1000,
firstUnenhancedHeight: nil
)
blockScannerMock.scanBlocksAtDidScanReturnValue = 1
do {
let nextContext = try await scanAction.run(with: syncContext) { event in
@ -36,7 +35,6 @@ final class ScanActionTests: ZcashTestCase {
}
}
XCTAssertTrue(loggerMock.debugFileFunctionLineCalled, "logger.debug(...) is expected to be called.")
XCTAssertTrue(blockScannerMock.scanBlocksAtTotalProgressRangeDidScanCalled, "blockScanner.scanBlocks(...) is expected to be called.")
let acResult = nextContext.checkStateIs(.clearAlreadyScannedBlocks)
XCTAssertTrue(acResult == .true, "Check of state failed with '\(acResult)'")
@ -55,7 +53,6 @@ final class ScanActionTests: ZcashTestCase {
do {
_ = try await scanAction.run(with: syncContext) { _ in }
XCTAssertFalse(loggerMock.debugFileFunctionLineCalled, "logger.debug(...) is not expected to be called.")
XCTAssertFalse(blockScannerMock.scanBlocksAtTotalProgressRangeDidScanCalled, "blockScanner.scanBlocks(...) is not expected to be called.")
} catch {
XCTFail("testScanAction_EarlyOutForNoDownloadAndScanRangeSet is not expected to fail. \(error)")
}
@ -73,11 +70,11 @@ final class ScanActionTests: ZcashTestCase {
latestScannedHeight: 1000,
firstUnenhancedHeight: nil
)
blockScannerMock.scanBlocksAtDidScanReturnValue = 1
do {
_ = try await scanAction.run(with: syncContext) { _ in }
XCTAssertFalse(loggerMock.debugFileFunctionLineCalled, "logger.debug(...) is not expected to be called.")
XCTAssertFalse(blockScannerMock.scanBlocksAtTotalProgressRangeDidScanCalled, "blockScanner.scanBlocks(...) is not expected to be called.")
} catch {
XCTFail("testScanAction_StartRangeHigherThanEndRange is not expected to fail. \(error)")
}
@ -88,26 +85,20 @@ final class ScanActionTests: ZcashTestCase {
let loggerMock = LoggerMock()
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
blockScannerMock.scanBlocksAtTotalProgressRangeDidScanClosure = { _, _, _ in 2 }
let scanAction = setupAction(blockScannerMock, loggerMock)
let syncContext = ActionContextMock.default()
syncContext.lastScannedHeight = 1001
syncContext.underlyingTotalProgressRange = 1000...1078
syncContext.underlyingSyncControlData = SyncControlData(
latestBlockHeight: 1078,
latestScannedHeight: 1000,
firstUnenhancedHeight: nil
)
blockScannerMock.scanBlocksAtDidScanReturnValue = 1
do {
_ = try await scanAction.run(with: syncContext) { _ in }
XCTAssertTrue(loggerMock.debugFileFunctionLineCalled, "logger.debug(...) is expected to be called.")
XCTAssertTrue(blockScannerMock.scanBlocksAtTotalProgressRangeDidScanCalled, "blockScanner.scanBlocks(...) is expected to be called.")
if let scanArguments = blockScannerMock.scanBlocksAtTotalProgressRangeDidScanReceivedArguments {
XCTAssertEqual(scanArguments.range.upperBound, 1078)
}
} catch {
XCTFail("testScanAction_EndRangeProperlySetLowerThanBatchSize is not expected to fail. \(error)")
}
@ -118,26 +109,20 @@ final class ScanActionTests: ZcashTestCase {
let loggerMock = LoggerMock()
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
blockScannerMock.scanBlocksAtTotalProgressRangeDidScanClosure = { _, _, _ in 2 }
let scanAction = setupAction(blockScannerMock, loggerMock)
let syncContext = ActionContextMock.default()
syncContext.lastScannedHeight = 1001
syncContext.underlyingTotalProgressRange = 1000...1978
syncContext.underlyingSyncControlData = SyncControlData(
latestBlockHeight: 1978,
latestScannedHeight: 1000,
firstUnenhancedHeight: nil
)
blockScannerMock.scanBlocksAtDidScanReturnValue = 1
do {
_ = try await scanAction.run(with: syncContext) { _ in }
XCTAssertTrue(loggerMock.debugFileFunctionLineCalled, "logger.debug(...) is expected to be called.")
XCTAssertTrue(blockScannerMock.scanBlocksAtTotalProgressRangeDidScanCalled, "blockScanner.scanBlocks(...) is expected to be called.")
if let scanArguments = blockScannerMock.scanBlocksAtTotalProgressRangeDidScanReceivedArguments {
XCTAssertEqual(scanArguments.range.upperBound, 1101)
}
} catch {
XCTFail("testScanAction_EndRangeProperlySetBatchSize is not expected to fail. \(error)")
}

View File

@ -23,10 +23,6 @@ class ActionContextMock: ActionContext {
}
var underlyingSyncControlData: SyncControlData!
var requestedRewindHeight: BlockHeight?
var totalProgressRange: CompactBlockRange {
get { return underlyingTotalProgressRange }
}
var underlyingTotalProgressRange: CompactBlockRange!
var processedHeight: BlockHeight {
get { return underlyingProcessedHeight }
}
@ -70,21 +66,6 @@ class ActionContextMock: ActionContext {
// MARK: - update
var updateTotalProgressRangeCallsCount = 0
var updateTotalProgressRangeCalled: Bool {
return updateTotalProgressRangeCallsCount > 0
}
var updateTotalProgressRangeReceivedTotalProgressRange: CompactBlockRange?
var updateTotalProgressRangeClosure: ((CompactBlockRange) async -> Void)?
func update(totalProgressRange: CompactBlockRange) async {
updateTotalProgressRangeCallsCount += 1
updateTotalProgressRangeReceivedTotalProgressRange = totalProgressRange
await updateTotalProgressRangeClosure!(totalProgressRange)
}
// MARK: - update
var updateProcessedHeightCallsCount = 0
var updateProcessedHeightCalled: Bool {
return updateProcessedHeightCallsCount > 0
@ -523,25 +504,25 @@ class BlockScannerMock: BlockScanner {
// MARK: - scanBlocks
var scanBlocksAtTotalProgressRangeDidScanThrowableError: Error?
var scanBlocksAtTotalProgressRangeDidScanCallsCount = 0
var scanBlocksAtTotalProgressRangeDidScanCalled: Bool {
return scanBlocksAtTotalProgressRangeDidScanCallsCount > 0
var scanBlocksAtDidScanThrowableError: Error?
var scanBlocksAtDidScanCallsCount = 0
var scanBlocksAtDidScanCalled: Bool {
return scanBlocksAtDidScanCallsCount > 0
}
var scanBlocksAtTotalProgressRangeDidScanReceivedArguments: (range: CompactBlockRange, totalProgressRange: CompactBlockRange, didScan: (BlockHeight, UInt32) async throws -> Void)?
var scanBlocksAtTotalProgressRangeDidScanReturnValue: BlockHeight!
var scanBlocksAtTotalProgressRangeDidScanClosure: ((CompactBlockRange, CompactBlockRange, @escaping (BlockHeight, UInt32) async throws -> Void) async throws -> BlockHeight)?
var scanBlocksAtDidScanReceivedArguments: (range: CompactBlockRange, didScan: (BlockHeight, UInt32) async throws -> Void)?
var scanBlocksAtDidScanReturnValue: BlockHeight!
var scanBlocksAtDidScanClosure: ((CompactBlockRange, @escaping (BlockHeight, UInt32) async throws -> Void) async throws -> BlockHeight)?
func scanBlocks(at range: CompactBlockRange, totalProgressRange: CompactBlockRange, didScan: @escaping (BlockHeight, UInt32) async throws -> Void) async throws -> BlockHeight {
if let error = scanBlocksAtTotalProgressRangeDidScanThrowableError {
func scanBlocks(at range: CompactBlockRange, didScan: @escaping (BlockHeight, UInt32) async throws -> Void) async throws -> BlockHeight {
if let error = scanBlocksAtDidScanThrowableError {
throw error
}
scanBlocksAtTotalProgressRangeDidScanCallsCount += 1
scanBlocksAtTotalProgressRangeDidScanReceivedArguments = (range: range, totalProgressRange: totalProgressRange, didScan: didScan)
if let closure = scanBlocksAtTotalProgressRangeDidScanClosure {
return try await closure(range, totalProgressRange, didScan)
scanBlocksAtDidScanCallsCount += 1
scanBlocksAtDidScanReceivedArguments = (range: range, didScan: didScan)
if let closure = scanBlocksAtDidScanClosure {
return try await closure(range, didScan)
} else {
return scanBlocksAtTotalProgressRangeDidScanReturnValue
return scanBlocksAtDidScanReturnValue
}
}