From be06b3d403e5fecd38ed4ab127abacc0bf876a99 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Fri, 15 Mar 2024 12:26:14 +0100 Subject: [PATCH] TreeState support - @str4d please check this implementation, I believe it's what you were looking for. - the new service's method getTreeState needs some documentation though TreeState support - Fixed the build, the swiftlint was complaining about a tuple length, we might consider to refactor is sometime later, for now I disabled swiftlint - fromState fix -1 TreeState support (#1394) - some fixes for offlineTests --- .../Block/Scan/BlockScanner.swift | 5 +++- .../Service/GRPC/LightWalletGRPCService.swift | 4 ++++ .../Modules/Service/LightWalletService.swift | 2 ++ .../Rust/ZcashRustBackend.swift | 1 + .../Synchronizer/Dependencies.swift | 2 ++ Tests/TestUtils/DarkSideWalletService.swift | 4 ++++ Tests/TestUtils/FakeService.swift | 4 ++++ .../AutoMockable.generated.swift | 24 +++++++++++++++++++ Tests/TestUtils/Stubs.swift | 4 ++-- 9 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Sources/ZcashLightClientKit/Block/Scan/BlockScanner.swift b/Sources/ZcashLightClientKit/Block/Scan/BlockScanner.swift index cf203f6b3..42cd4d959 100644 --- a/Sources/ZcashLightClientKit/Block/Scan/BlockScanner.swift +++ b/Sources/ZcashLightClientKit/Block/Scan/BlockScanner.swift @@ -23,6 +23,7 @@ protocol BlockScanner { struct BlockScannerImpl { let config: BlockScannerConfig let rustBackend: ZcashRustBackendWelding + let service: LightWalletService let transactionRepository: TransactionRepository let metrics: SDKMetrics let logger: Logger @@ -56,7 +57,9 @@ extension BlockScannerImpl: BlockScanner { let scanSummary: ScanSummary let scanStartTime = Date() do { - scanSummary = try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), limit: batchSize) + let fromState = try await service.getTreeState(BlockID(height: startHeight - 1)) + + scanSummary = try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), fromState: fromState, limit: batchSize) } catch { logger.debug("block scanning failed with error: \(String(describing: error))") throw error diff --git a/Sources/ZcashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift b/Sources/ZcashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift index c430786eb..4794b108c 100644 --- a/Sources/ZcashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +++ b/Sources/ZcashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift @@ -277,6 +277,10 @@ extension LightWalletGRPCService: LightWalletService { } } } + + func getTreeState(_ id: BlockID) async throws -> TreeState { + try await compactTxStreamer.getTreeState(id) + } func closeConnection() { _ = channel.close() diff --git a/Sources/ZcashLightClientKit/Modules/Service/LightWalletService.swift b/Sources/ZcashLightClientKit/Modules/Service/LightWalletService.swift index b6f3cf60b..b5b4fe8ed 100644 --- a/Sources/ZcashLightClientKit/Modules/Service/LightWalletService.swift +++ b/Sources/ZcashLightClientKit/Modules/Service/LightWalletService.swift @@ -196,4 +196,6 @@ protocol LightWalletService: AnyObject { /// - Parameters: /// - request: Request to send to GetSubtreeRoots. func getSubtreeRoots(_ request: GetSubtreeRootsArg) -> AsyncThrowingStream + + func getTreeState(_ id: BlockID) async throws -> TreeState } diff --git a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift index 1f0af88df..ea5866487 100644 --- a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift +++ b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift @@ -859,6 +859,7 @@ extension FfiScanProgress { } } +// swiftlint:disable large_tuple line_length struct FfiTxId { var tuple: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) var array: [UInt8] { diff --git a/Sources/ZcashLightClientKit/Synchronizer/Dependencies.swift b/Sources/ZcashLightClientKit/Synchronizer/Dependencies.swift index 05c48053f..40b2ad767 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/Dependencies.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/Dependencies.swift @@ -120,6 +120,7 @@ enum Dependencies { } container.register(type: BlockScanner.self, isSingleton: true) { di in + let service = di.resolve(LightWalletService.self) let rustBackend = di.resolve(ZcashRustBackendWelding.self) let transactionRepository = di.resolve(TransactionRepository.self) let metrics = di.resolve(SDKMetrics.self) @@ -133,6 +134,7 @@ enum Dependencies { return BlockScannerImpl( config: blockScannerConfig, rustBackend: rustBackend, + service: service, transactionRepository: transactionRepository, metrics: metrics, logger: logger diff --git a/Tests/TestUtils/DarkSideWalletService.swift b/Tests/TestUtils/DarkSideWalletService.swift index 60e3f90e8..7cc86a864 100644 --- a/Tests/TestUtils/DarkSideWalletService.swift +++ b/Tests/TestUtils/DarkSideWalletService.swift @@ -190,6 +190,10 @@ class DarksideWalletService: LightWalletService { func getSubtreeRoots(_ request: ZcashLightClientKit.GetSubtreeRootsArg) -> AsyncThrowingStream { service.getSubtreeRoots(request) } + + func getTreeState(_ id: BlockID) async throws -> TreeState { + try await service.getTreeState(id) + } } enum DarksideWalletDConstants: NetworkConstants { diff --git a/Tests/TestUtils/FakeService.swift b/Tests/TestUtils/FakeService.swift index 07e2d74bd..3358f5191 100644 --- a/Tests/TestUtils/FakeService.swift +++ b/Tests/TestUtils/FakeService.swift @@ -82,4 +82,8 @@ class MockLightWalletService: LightWalletService { func getSubtreeRoots(_ request: ZcashLightClientKit.GetSubtreeRootsArg) -> AsyncThrowingStream { service.getSubtreeRoots(request) } + + func getTreeState(_ id: BlockID) async throws -> TreeState { + try await service.getTreeState(id) + } } diff --git a/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift b/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift index f8606891e..1f3197968 100644 --- a/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift +++ b/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift @@ -963,6 +963,30 @@ class LightWalletServiceMock: LightWalletService { } } + // MARK: - getTreeState + + var getTreeStateThrowableError: Error? + var getTreeStateCallsCount = 0 + var getTreeStateCalled: Bool { + return getTreeStateCallsCount > 0 + } + var getTreeStateReceivedId: BlockID? + var getTreeStateReturnValue: TreeState! + var getTreeStateClosure: ((BlockID) async throws -> TreeState)? + + func getTreeState(_ id: BlockID) async throws -> TreeState { + if let error = getTreeStateThrowableError { + throw error + } + getTreeStateCallsCount += 1 + getTreeStateReceivedId = id + if let closure = getTreeStateClosure { + return try await closure(id) + } else { + return getTreeStateReturnValue + } + } + } class LightWalletdInfoMock: LightWalletdInfo { diff --git a/Tests/TestUtils/Stubs.swift b/Tests/TestUtils/Stubs.swift index f5f335211..b552b0791 100644 --- a/Tests/TestUtils/Stubs.swift +++ b/Tests/TestUtils/Stubs.swift @@ -102,8 +102,8 @@ class RustBackendMockHelper { try await rustBackend.suggestScanRanges() } - await rustBackendMock.setScanBlocksFromHeightLimitClosure() { fromHeight, limit in - try await rustBackend.scanBlocks(fromHeight: fromHeight, limit: limit) + await rustBackendMock.setScanBlocksFromHeightFromStateLimitClosure { fromHeight, fromState, limit in + try await rustBackend.scanBlocks(fromHeight: fromHeight, fromState: fromState, limit: limit) } }