ZcashLightClientKit/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputs.swift

77 lines
2.6 KiB
Swift

//
// FetchUnspentTxOutputs.swift
// ZcashLightClientKit
//
// Created by Francisco Gindre on 6/2/21.
//
import Foundation
extension CompactBlockProcessor {
enum FetchUTXOError: Error {
case clearingFailed(_ error: Error?)
case fetchFailed(error: Error)
}
func fetchUnspentTxOutputs(range: CompactBlockRange) async throws {
try Task.checkCancellation()
state = .fetching
do {
let tAddresses = try accountRepository.getAll()
.map { $0.account }
.map {
try rustBackend.listTransparentReceivers(
dbData: config.dataDb,
account: Int32($0),
networkType: config.network.networkType
)
}
.flatMap({ $0 })
var utxos: [UnspentTransactionOutputEntity] = []
let stream: AsyncThrowingStream<UnspentTransactionOutputEntity, Error> = downloader.fetchUnspentTransactionOutputs(tAddresses: tAddresses.map { $0.stringEncoded }, startHeight: config.walletBirthday)
for try await transaction in stream {
utxos.append(transaction)
}
var refreshed: [UnspentTransactionOutputEntity] = []
var skipped: [UnspentTransactionOutputEntity] = []
for utxo in utxos {
do {
try rustBackend.putUnspentTransparentOutput(
dbData: config.dataDb,
txid: utxo.txid.bytes,
index: utxo.index,
script: utxo.script.bytes,
value: Int64(utxo.valueZat),
height: utxo.height,
networkType: config.network.networkType
) ? refreshed.append(utxo) : skipped.append(utxo)
} catch {
LoggerProxy.error("failed to put utxo - error: \(error)")
skipped.append(utxo)
}
}
let result = (inserted: refreshed, skipped: skipped)
NotificationCenter.default.mainThreadPost(
name: .blockProcessorStoredUTXOs,
object: self,
userInfo: [CompactBlockProcessorNotificationKey.refreshedUTXOs: result]
)
if Task.isCancelled {
LoggerProxy.debug("Warning: fetchUnspentTxOutputs on range \(range) cancelled")
} else {
await processBatchFinished(range: range)
}
} catch {
throw error
}
}
}