From b684a2f4864934cbd547159ac5922dbc3b54e27d Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 30 Aug 2022 16:00:48 +0200 Subject: [PATCH] [#474] FetchUnspentTxOutputsOperation to async/await (#514) - wrapped to Task - downloader uses the new async API --- .../FetchUnspentTxOutputsOperation.swift | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputsOperation.swift b/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputsOperation.swift index ad644a4e..06765bc2 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputsOperation.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputsOperation.swift @@ -24,7 +24,9 @@ class FetchUnspentTxOutputsOperation: ZcashOperation { private var startHeight: BlockHeight private var network: NetworkType private var dataDb: URL - + private var cancelableTask: Task? + private var done = false + init( accountRepository: AccountRepository, downloader: CompactBlockDownloading, @@ -49,32 +51,41 @@ class FetchUnspentTxOutputsOperation: ZcashOperation { self.startedHandler?() - do { - let tAddresses = try accountRepository.getAll().map({ $0.transparentAddress }) + cancelableTask = Task { do { - for tAddress in tAddresses { - guard try self.rustbackend.clearUtxos( - dbData: dataDb, - address: tAddress, - sinceHeight: startHeight - 1, - networkType: network - ) >= 0 else { - throw rustbackend.lastError() ?? RustWeldingError.genericError(message: "attempted to clear utxos but -1 was returned") + let tAddresses = try accountRepository.getAll().map({ $0.transparentAddress }) + do { + for tAddress in tAddresses { + guard try self.rustbackend.clearUtxos( + dbData: dataDb, + address: tAddress, + sinceHeight: startHeight - 1, + networkType: network + ) >= 0 else { + throw rustbackend.lastError() ?? RustWeldingError.genericError(message: "attempted to clear utxos but -1 was returned") + } } + } catch { + throw FetchUTXOError.clearingFailed(error) } + + var utxos: [UnspentTransactionOutputEntity] = [] + let stream: AsyncThrowingStream = downloader.fetchUnspentTransactionOutputs(tAddresses: tAddresses, startHeight: startHeight) + for try await transaction in stream { + utxos.append(transaction) + } + + let result = storeUTXOs(utxos, in: dataDb) + + self.fetchedUTXOsHandler?(result) + self.done = true } catch { - throw FetchUTXOError.clearingFailed(error) + self.fail(error: error) } - - // TODO: will be replaced by new async API, issue 474 - // https://github.com/zcash/ZcashLightClientKit/issues/474 - let utxos: [UnspentTransactionOutputEntity] = try downloader.fetchUnspentTransactionOutputs(tAddresses: tAddresses, startHeight: startHeight) - - let result = storeUTXOs(utxos, in: dataDb) - - self.fetchedUTXOsHandler?(result) - } catch { - self.fail(error: error) + } + + while !done && !isCancelled { + sleep(1) } } @@ -102,4 +113,14 @@ class FetchUnspentTxOutputsOperation: ZcashOperation { return (inserted: refreshed, skipped: skipped) } + + override func fail(error: Error? = nil) { + self.cancelableTask?.cancel() + super.fail(error: error) + } + + override func cancel() { + self.cancelableTask?.cancel() + super.cancel() + } }