MobileCoin-Swift/Sources/Fog/FogViewKeyScanner.swift
Kyle Fleming 74a5c6f3fe
Continued logging cleanup (#17)
Co-authored-by: Eran Rundstein <eran@rundste.in>
2021-04-05 11:06:57 -07:00

75 lines
2.8 KiB
Swift

//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable multiline_function_chains
import Foundation
import LibMobileCoin
final class FogViewKeyScanner {
private let accountKey: AccountKey
private let fogBlockService: FogBlockService
init(accountKey: AccountKey, fogBlockService: FogBlockService) {
self.accountKey = accountKey
self.fogBlockService = fogBlockService
}
func viewKeyScanBlocks(
blockRanges: [Range<UInt64>],
completion: @escaping (Result<[KnownTxOut], ConnectionError>) -> Void
) {
logger.info(
"Fetching block ranges: \(blockRanges.map { "[\($0.lowerBound), \($0.upperBound))" })",
logFunction: false)
fetchBlocksTxOuts(ranges: blockRanges) {
completion($0.map { blocksTxOuts in
logger.info(
"View key scanning blocks: " +
"\(blockRanges.map { "[\($0.lowerBound), \($0.upperBound))" }) " +
"containing \(blocksTxOuts.count) TxOuts",
logFunction: false)
let foundTxOuts = blocksTxOuts.compactMap {
$0.decrypt(accountKey: self.accountKey)
}
logger.info(
"View key scanning missed blocks found \(redacting: foundTxOuts.count) TxOuts",
logFunction: false)
return foundTxOuts
})
}
}
func fetchBlocksTxOuts(
ranges: [Range<UInt64>],
completion: @escaping (Result<[LedgerTxOut], ConnectionError>) -> Void
) {
var request = FogLedger_BlockRequest()
request.rangeValues = ranges
fogBlockService.getBlocks(request: request) {
completion($0.flatMap { response in
response.blocks.flatMap { responseBlock -> [Result<LedgerTxOut, ConnectionError>] in
let globalIndexStart =
responseBlock.globalTxoCount - UInt64(responseBlock.outputs.count)
return responseBlock.outputs.enumerated().map { outputIndex, output in
guard let partialTxOut = PartialTxOut(output) else {
let errorMessage =
"Fog Block service returned invalid TxOut: \(output)"
logger.error(errorMessage, logFunction: false)
return .failure(.invalidServerResponse(errorMessage))
}
return .success(LedgerTxOut(
partialTxOut,
globalIndex: globalIndexStart + UInt64(outputIndex),
block: responseBlock.metadata))
}
}.collectResult()
})
}
}
}