parent
ce8fcdf3cc
commit
75a9e3622e
|
@ -10,15 +10,16 @@ import Foundation
|
|||
actor ActionContext {
|
||||
var state: CBPState
|
||||
var syncRanges: SyncRanges
|
||||
var totalProgressRange: CompactBlockRange = 0...0
|
||||
|
||||
init(state: CBPState) {
|
||||
self.state = state
|
||||
syncRanges = SyncRanges.empty
|
||||
}
|
||||
|
||||
func update(state: CBPState) async {
|
||||
self.state = state
|
||||
}
|
||||
func update(state: CBPState) async { self.state = state }
|
||||
func update(syncRanges: SyncRanges) async { self.syncRanges = syncRanges }
|
||||
func update(totalProgressRange: CompactBlockRange) async { self.totalProgressRange = totalProgressRange }
|
||||
}
|
||||
|
||||
enum CBPState: CaseIterable {
|
||||
|
|
|
@ -8,7 +8,34 @@
|
|||
import Foundation
|
||||
|
||||
class ComputeSyncRangesAction {
|
||||
init(container: DIContainer) { }
|
||||
let config: CompactBlockProcessorNG.Configuration
|
||||
let downloaderService: BlockDownloaderService
|
||||
let internalSyncProgress: InternalSyncProgress
|
||||
let latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
let logger: Logger
|
||||
init(container: DIContainer, config: CompactBlockProcessorNG.Configuration) {
|
||||
self.config = config
|
||||
downloaderService = container.resolve(BlockDownloaderService.self)
|
||||
internalSyncProgress = container.resolve(InternalSyncProgress.self)
|
||||
latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
|
||||
logger = container.resolve(Logger.self)
|
||||
}
|
||||
|
||||
/// It may happen that sync process start with syncing blocks that were downloaded but not synced in previous run of the sync process. This
|
||||
/// methods analyses what must be done and computes range that should be used to compute reported progress.
|
||||
private func computeTotalProgressRange(from syncRanges: SyncRanges) -> CompactBlockRange {
|
||||
guard syncRanges.downloadedButUnscannedRange != nil || syncRanges.downloadAndScanRange != nil else {
|
||||
// In this case we are sure that no downloading or scanning happens so this returned range won't be even used. And it's easier to return
|
||||
// this "fake" range than to handle nil.
|
||||
return 0...0
|
||||
}
|
||||
|
||||
// Thanks to guard above we can be sure that one of these two ranges is not nil.
|
||||
let lowerBound = syncRanges.downloadedButUnscannedRange?.lowerBound ?? syncRanges.downloadAndScanRange?.lowerBound ?? 0
|
||||
let upperBound = syncRanges.downloadAndScanRange?.upperBound ?? syncRanges.downloadedButUnscannedRange?.upperBound ?? 0
|
||||
|
||||
return lowerBound...upperBound
|
||||
}
|
||||
}
|
||||
|
||||
extension ComputeSyncRangesAction: Action {
|
||||
|
@ -16,7 +43,47 @@ extension ComputeSyncRangesAction: Action {
|
|||
// call internalSyncProgress and compute sync ranges and store them in context
|
||||
// if there is nothing sync just switch to finished state
|
||||
|
||||
await context.update(state: .checksBeforeSync)
|
||||
let latestDownloadHeight = try await downloaderService.lastDownloadedBlockHeight()
|
||||
|
||||
await internalSyncProgress.migrateIfNeeded(latestDownloadedBlockHeightFromCacheDB: latestDownloadHeight)
|
||||
|
||||
await latestBlocksDataProvider.updateScannedData()
|
||||
await latestBlocksDataProvider.updateBlockData()
|
||||
|
||||
let nextState = await internalSyncProgress.computeNextState(
|
||||
latestBlockHeight: latestBlocksDataProvider.latestBlockHeight,
|
||||
latestScannedHeight: latestBlocksDataProvider.latestScannedHeight,
|
||||
walletBirthday: config.walletBirthday
|
||||
)
|
||||
|
||||
switch nextState {
|
||||
case .finishProcessing:
|
||||
await context.update(state: .finished)
|
||||
case .processNewBlocks(let ranges):
|
||||
let totalProgressRange = computeTotalProgressRange(from: ranges)
|
||||
await context.update(totalProgressRange: totalProgressRange)
|
||||
await context.update(syncRanges: ranges)
|
||||
await context.update(state: .checksBeforeSync)
|
||||
|
||||
logger.debug("""
|
||||
Syncing with ranges:
|
||||
downloaded but not scanned: \
|
||||
\(ranges.downloadedButUnscannedRange?.lowerBound ?? -1)...\(ranges.downloadedButUnscannedRange?.upperBound ?? -1)
|
||||
download and scan: \(ranges.downloadAndScanRange?.lowerBound ?? -1)...\(ranges.downloadAndScanRange?.upperBound ?? -1)
|
||||
enhance range: \(ranges.enhanceRange?.lowerBound ?? -1)...\(ranges.enhanceRange?.upperBound ?? -1)
|
||||
fetchUTXO range: \(ranges.fetchUTXORange?.lowerBound ?? -1)...\(ranges.fetchUTXORange?.upperBound ?? -1)
|
||||
total progress range: \(totalProgressRange.lowerBound)...\(totalProgressRange.upperBound)
|
||||
""")
|
||||
|
||||
case let .wait(latestHeight, latestDownloadHeight):
|
||||
// Lightwalletd might be syncing
|
||||
logger.info(
|
||||
"Lightwalletd might be syncing: latest downloaded block height is: \(latestDownloadHeight) " +
|
||||
"while latest blockheight is reported at: \(latestHeight)"
|
||||
)
|
||||
await context.update(state: .finished)
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue