Merge pull request #622 from Chlup/619_fix_incorrect_resume

[#619] Correctly resume syncing process in scanning phase
This commit is contained in:
Michal Fousek 2022-11-11 15:11:50 +01:00 committed by GitHub
commit 6407820f77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 17 deletions

View File

@ -140,8 +140,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
"state" : {
"revision" : "70bf6ae6538943f2b8453f424e607a05f4dc7be6",
"version" : "0.1.0-beta.2"
"revision" : "7febbfd74a7d963ec206e01f8ef6090bb8cee523",
"version" : "0.1.0-beta.3"
}
}
],

View File

@ -30,7 +30,7 @@ extension CompactBlockProcessor {
throw LightWalletServiceError.generalError(message: "missing target height on compactBlockStreamDownload")
}
try Task.checkCancellation()
let latestDownloaded = try await storage.latestHeightAsync()
let latestDownloaded = try storage.latestBlockHeight()
let startHeight = max(startHeight ?? BlockHeight.empty(), latestDownloaded)
let stream = service.blockStream(

View File

@ -593,18 +593,26 @@ public actor CompactBlockProcessor {
}
/// Processes new blocks on the given range based on the configuration set for this instance
func processNewBlocks(range: CompactBlockRange) async {
func processNewBlocks(range: CompactBlockRange, latestBlockHeight: BlockHeight) async {
self.foundBlocks = true
self.backoffTimer?.invalidate()
self.backoffTimer = nil
cancelableTask = Task(priority: .userInitiated) {
do {
try await compactBlockStreamDownload(
blockBufferSize: config.downloadBufferSize,
startHeight: range.lowerBound,
targetHeight: range.upperBound
)
let lastDownloadedBlockHeight = try downloader.lastDownloadedBlockHeight()
// It may happen that sync process is interrupted in scanning phase. And then when sync process is resumed we already have
// blocks downloaded.
//
// Therefore we want to skip downloading in case that we already have everything downloaded.
if lastDownloadedBlockHeight < latestBlockHeight {
try await compactBlockStreamDownload(
blockBufferSize: config.downloadBufferSize,
startHeight: range.lowerBound,
targetHeight: range.upperBound
)
}
try await compactBlockValidation()
try await compactBlockBatchScanning(range: range)
try await compactBlockEnhancement(range: range)
@ -748,6 +756,7 @@ public actor CompactBlockProcessor {
let nextState = try await NextStateHelper.nextStateAsync(
service: self.service,
downloader: self.downloader,
transactionRepository: transactionRepository,
config: self.config,
rustBackend: self.rustBackend
)
@ -755,10 +764,10 @@ public actor CompactBlockProcessor {
case .finishProcessing(let height):
self.latestBlockHeight = height
await self.processingFinished(height: height)
case .processNewBlocks(let range):
case .processNewBlocks(let range, let latestBlockHeight):
self.latestBlockHeight = range.upperBound
self.lowerBoundHeight = range.lowerBound
await self.processNewBlocks(range: range)
await self.processNewBlocks(range: range, latestBlockHeight: latestBlockHeight)
case let .wait(latestHeight, latestDownloadHeight):
// Lightwalletd might be syncing
self.lowerBoundHeight = latestDownloadHeight
@ -1132,6 +1141,7 @@ extension CompactBlockProcessor {
static func nextStateAsync(
service: LightWalletService,
downloader: CompactBlockDownloading,
transactionRepository: TransactionRepository,
config: Configuration,
rustBackend: ZcashRustBackendWelding.Type
) async throws -> NextState {
@ -1145,11 +1155,22 @@ extension CompactBlockProcessor {
localNetwork: config.network,
rustBackend: rustBackend
)
// get latest block height
let latestDownloadedBlockHeight: BlockHeight = max(config.walletBirthday, try downloader.lastDownloadedBlockHeight())
let lastDownloadedBlockHeight = try downloader.lastDownloadedBlockHeight()
let lastScannedHeight = try transactionRepository.lastScannedHeight()
let latestBlockheight = try service.latestBlockHeight()
// Syncing process can be interrupted in any phase. And here it must be detected in which phase is syncing process.
let latestDownloadedBlockHeight: BlockHeight
// This means that there are some blocks that are not downloaded yet.
if lastDownloadedBlockHeight < latestBlockheight {
latestDownloadedBlockHeight = max(config.walletBirthday, lastDownloadedBlockHeight)
} else {
// Here all the blocks are downloaded and last scan height should be then used to compute processing range.
latestDownloadedBlockHeight = max(config.walletBirthday, lastScannedHeight)
}
if latestDownloadedBlockHeight < latestBlockheight {
return NextState.processNewBlocks(
@ -1157,7 +1178,8 @@ extension CompactBlockProcessor {
latestHeight: latestBlockheight,
latestDownloadedHeight: latestDownloadedBlockHeight,
walletBirthday: config.walletBirthday
)
),
latestBlockHeight: latestBlockheight
)
} else if latestBlockheight == latestDownloadedBlockHeight {
return .finishProcessing(height: latestBlockheight)

View File

@ -10,7 +10,7 @@ import Foundation
extension CompactBlockProcessor {
enum NextState {
case finishProcessing(height: BlockHeight)
case processNewBlocks(range: CompactBlockRange)
case processNewBlocks(range: CompactBlockRange, latestBlockHeight: BlockHeight)
case wait(latestHeight: BlockHeight, latestDownloadHeight: BlockHeight)
}
@ -24,6 +24,7 @@ extension CompactBlockProcessor {
return try await CompactBlockProcessor.NextStateHelper.nextStateAsync(
service: service,
downloader: downloader,
transactionRepository: transactionRepository,
config: config,
rustBackend: rustBackend
)