[#1273] SynchronizerState not always up to date

- latestBlockHeight (chain tip) reported in the SynchronizerState to the clients is now updated every 10mins at most, typically with every sync run (10-30s)
- fully and max scanned heights update fixed
- new mocks provided and tests fixed
This commit is contained in:
Lukas Korba 2023-09-18 11:01:58 +02:00
parent 0abe7f8cdf
commit 6b8d95906a
6 changed files with 49 additions and 14 deletions

View File

@ -11,12 +11,14 @@ final class ScanAction {
let configProvider: CompactBlockProcessor.ConfigProvider
let blockScanner: BlockScanner
let rustBackend: ZcashRustBackendWelding
let latestBlocksDataProvider: LatestBlocksDataProvider
let logger: Logger
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider
blockScanner = container.resolve(BlockScanner.self)
rustBackend = container.resolve(ZcashRustBackendWelding.self)
latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
logger = container.resolve(Logger.self)
}
@ -54,7 +56,8 @@ extension ScanAction: Action {
let processedHeight = await context.processedHeight
let incrementedprocessedHeight = processedHeight + BlockHeight(increment)
await context.update(processedHeight: incrementedprocessedHeight)
await self?.latestBlocksDataProvider.updateScannedData()
// report scan progress only if it's available
if let scanProgress = try? await self?.rustBackend.getScanProgress() {
let progress = try scanProgress.progress()

View File

@ -11,12 +11,14 @@ final class UpdateChainTipAction {
let rustBackend: ZcashRustBackendWelding
let downloader: BlockDownloader
let service: LightWalletService
let latestBlocksDataProvider: LatestBlocksDataProvider
let logger: Logger
init(container: DIContainer) {
service = container.resolve(LightWalletService.self)
downloader = container.resolve(BlockDownloader.self)
rustBackend = container.resolve(ZcashRustBackendWelding.self)
latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
logger = container.resolve(Logger.self)
}
@ -26,6 +28,7 @@ final class UpdateChainTipAction {
logger.info("Latest block height is \(latestBlockHeight)")
try await rustBackend.updateChainTip(height: Int32(latestBlockHeight))
await context.update(lastChainTipUpdateTime: time)
await latestBlocksDataProvider.update(latestBlockHeight)
}
}

View File

@ -16,6 +16,7 @@ protocol LatestBlocksDataProvider {
func updateScannedData() async
func updateBlockData() async
func updateWalletBirthday(_ walletBirthday: BlockHeight) async
func update(_ latestBlockHeight: BlockHeight) async
}
actor LatestBlocksDataProviderImpl: LatestBlocksDataProvider {
@ -41,13 +42,18 @@ actor LatestBlocksDataProviderImpl: LatestBlocksDataProvider {
}
func updateBlockData() async {
if let newLatestBlockHeight = try? await service.latestBlockHeight(),
latestBlockHeight < newLatestBlockHeight {
latestBlockHeight = newLatestBlockHeight
if let newLatestBlockHeight = try? await service.latestBlockHeight() {
await update(newLatestBlockHeight)
}
}
func updateWalletBirthday(_ walletBirthday: BlockHeight) async {
self.walletBirthday = walletBirthday
}
func update(_ newLatestBlockHeight: BlockHeight) async {
if latestBlockHeight < newLatestBlockHeight {
latestBlockHeight = newLatestBlockHeight
}
}
}

View File

@ -13,7 +13,7 @@ final class ScanActionTests: ZcashTestCase {
func testScanAction_NextAction() async throws {
let blockScannerMock = BlockScannerMock()
let loggerMock = LoggerMock()
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
let scanAction = setupAction(blockScannerMock, loggerMock)
@ -46,7 +46,7 @@ final class ScanActionTests: ZcashTestCase {
func testScanAction_EarlyOutForNoDownloadAndScanRangeSet() async throws {
let blockScannerMock = BlockScannerMock()
let loggerMock = LoggerMock()
let scanAction = setupAction(blockScannerMock, loggerMock)
let syncContext = ActionContextMock.default()
@ -83,7 +83,7 @@ final class ScanActionTests: ZcashTestCase {
func testScanAction_EndRangeProperlySetLowerThanBatchSize() async throws {
let blockScannerMock = BlockScannerMock()
let loggerMock = LoggerMock()
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
let scanAction = setupAction(blockScannerMock, loggerMock)
@ -107,7 +107,7 @@ final class ScanActionTests: ZcashTestCase {
func testScanAction_EndRangeProperlySetBatchSize() async throws {
let blockScannerMock = BlockScannerMock()
let loggerMock = LoggerMock()
loggerMock.debugFileFunctionLineClosure = { _, _, _, _ in }
let scanAction = setupAction(blockScannerMock, loggerMock)
@ -130,7 +130,8 @@ final class ScanActionTests: ZcashTestCase {
private func setupAction(
_ blockScannerMock: BlockScannerMock,
_ loggerMock: LoggerMock
_ loggerMock: LoggerMock,
_ latestBlocksDataProvider: LatestBlocksDataProvider = LatestBlocksDataProviderMock()
) -> ScanAction {
let rustBackendMock = ZcashRustBackendWeldingMock(
consensusBranchIdForHeightClosure: { height in
@ -142,7 +143,8 @@ final class ScanActionTests: ZcashTestCase {
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in rustBackendMock }
mockContainer.mock(type: BlockScanner.self, isSingleton: true) { _ in blockScannerMock }
mockContainer.mock(type: Logger.self, isSingleton: true) { _ in loggerMock }
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in latestBlocksDataProvider }
let config: CompactBlockProcessor.Configuration = .standard(
for: ZcashNetworkBuilder.network(for: .testnet), walletBirthday: 0
)

View File

@ -27,11 +27,13 @@ final class UpdateChainTipActionTests: ZcashTestCase {
func testUpdateChainTipAction_UpdateChainTipTimeTriggered() async throws {
let loggerMock = LoggerMock()
let blockDownloaderMock = BlockDownloaderMock()
let latestBlocksDataProvider = LatestBlocksDataProviderMock()
loggerMock.infoFileFunctionLineClosure = { _, _, _, _ in }
blockDownloaderMock.stopDownloadClosure = { }
let updateChainTipAction = await setupAction(loggerMock, blockDownloaderMock)
latestBlocksDataProvider.updateClosure = { _ in }
let updateChainTipAction = await setupAction(loggerMock, blockDownloaderMock, latestBlocksDataProvider)
do {
let context = ActionContextMock.default()
@ -53,11 +55,13 @@ final class UpdateChainTipActionTests: ZcashTestCase {
func testUpdateChainTipAction_UpdateChainTipPrevActionTriggered() async throws {
let loggerMock = LoggerMock()
let blockDownloaderMock = BlockDownloaderMock()
let latestBlocksDataProvider = LatestBlocksDataProviderMock()
loggerMock.infoFileFunctionLineClosure = { _, _, _, _ in }
blockDownloaderMock.stopDownloadClosure = { }
latestBlocksDataProvider.updateClosure = { _ in }
let updateChainTipAction = await setupAction(loggerMock, blockDownloaderMock)
let updateChainTipAction = await setupAction(loggerMock, blockDownloaderMock, latestBlocksDataProvider)
do {
let context = ActionContextMock.default()
@ -104,7 +108,8 @@ final class UpdateChainTipActionTests: ZcashTestCase {
private func setupAction(
_ loggerMock: LoggerMock = LoggerMock(),
_ blockDownloaderMock: BlockDownloaderMock = BlockDownloaderMock()
_ blockDownloaderMock: BlockDownloaderMock = BlockDownloaderMock(),
_ latestBlocksDataProvider: LatestBlocksDataProvider = LatestBlocksDataProviderMock()
) async -> UpdateChainTipAction {
let config: CompactBlockProcessor.Configuration = .standard(
for: ZcashNetworkBuilder.network(for: underlyingNetworkType), walletBirthday: 0
@ -133,6 +138,7 @@ final class UpdateChainTipActionTests: ZcashTestCase {
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in serviceMock }
mockContainer.mock(type: Logger.self, isSingleton: true) { _ in loggerMock }
mockContainer.mock(type: BlockDownloader.self, isSingleton: true) { _ in blockDownloaderMock }
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in latestBlocksDataProvider }
return UpdateChainTipAction(container: mockContainer)
}

View File

@ -712,6 +712,21 @@ class LatestBlocksDataProviderMock: LatestBlocksDataProvider {
await updateWalletBirthdayClosure!(walletBirthday)
}
// MARK: - update
var updateCallsCount = 0
var updateCalled: Bool {
return updateCallsCount > 0
}
var updateReceivedLatestBlockHeight: BlockHeight?
var updateClosure: ((BlockHeight) async -> Void)?
func update(_ latestBlockHeight: BlockHeight) async {
updateCallsCount += 1
updateReceivedLatestBlockHeight = latestBlockHeight
await updateClosure!(latestBlockHeight)
}
}
class LightWalletServiceMock: LightWalletService {