Migrate to latest in-progress revision of Rust crates
- New backend method `ZcashRustBackend.isSeedRelevantToWallet` - `ZcashRustBackend.scanBlocks` now takes a `fromState` argument. Co-authored-by: Lukas Korba <lukas.korba@seznam.cz>
This commit is contained in:
parent
86defc8b4a
commit
a5a0ef0ac1
|
@ -176,7 +176,7 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
||||
"state" : {
|
||||
"revision" : "4eccfb5ea825f5f0ebb3cab964d08ef21103feb4"
|
||||
"revision" : "d1d038d653806f23fc291931823d95f2dc411486"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
|
||||
"state" : {
|
||||
"revision" : "4eccfb5ea825f5f0ebb3cab964d08ef21103feb4"
|
||||
"revision" : "d1d038d653806f23fc291931823d95f2dc411486"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -16,8 +16,8 @@ let package = Package(
|
|||
dependencies: [
|
||||
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.19.1"),
|
||||
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1"),
|
||||
// Compiled from revision `c2ac47300d062b76134c515589301b202277e3fa`.
|
||||
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "4eccfb5ea825f5f0ebb3cab964d08ef21103feb4")
|
||||
// Compiled from revision `70cce1272c26ed52fbe7bfa334be781373b64bfd`.
|
||||
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "d1d038d653806f23fc291931823d95f2dc411486")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -101,8 +101,8 @@ extension ZcashTransaction.Output {
|
|||
static let rawID = Expression<Blob>("txid")
|
||||
static let pool = Expression<Int>("output_pool")
|
||||
static let index = Expression<Int>("output_index")
|
||||
static let toAccount = Expression<Int?>("to_account")
|
||||
static let fromAccount = Expression<Int?>("from_account")
|
||||
static let toAccount = Expression<Int?>("to_account_id")
|
||||
static let fromAccount = Expression<Int?>("from_account_id")
|
||||
static let toAddress = Expression<String?>("to_address")
|
||||
static let value = Expression<Int64>("value")
|
||||
static let isChange = Expression<Bool>("is_change")
|
||||
|
|
|
@ -329,6 +329,10 @@ public enum ZcashError: Equatable, Error {
|
|||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// ZRUST0058
|
||||
case rustListAccounts(_ rustError: String)
|
||||
/// Error from rust layer when calling ZcashRustBackend.isSeedRelevantToWallet
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
/// ZRUST0059
|
||||
case rustIsSeedRelevantToWallet(_ rustError: String)
|
||||
/// SQLite query failed when fetching all accounts from the database.
|
||||
/// - `sqliteError` is error produced by SQLite library.
|
||||
/// ZADAO0001
|
||||
|
@ -686,6 +690,7 @@ public enum ZcashError: Equatable, Error {
|
|||
case .rustGetWalletSummary: return "Error from rust layer when calling ZcashRustBackend.getWalletSummary"
|
||||
case .rustProposeTransferFromURI: return "Error from rust layer when calling ZcashRustBackend."
|
||||
case .rustListAccounts: return "Error from rust layer when calling ZcashRustBackend."
|
||||
case .rustIsSeedRelevantToWallet: return "Error from rust layer when calling ZcashRustBackend.isSeedRelevantToWallet"
|
||||
case .accountDAOGetAll: return "SQLite query failed when fetching all accounts from the database."
|
||||
case .accountDAOGetAllCantDecode: return "Fetched accounts from SQLite but can't decode them."
|
||||
case .accountDAOFindBy: return "SQLite query failed when seaching for accounts in the database."
|
||||
|
@ -862,6 +867,7 @@ public enum ZcashError: Equatable, Error {
|
|||
case .rustGetWalletSummary: return .rustGetWalletSummary
|
||||
case .rustProposeTransferFromURI: return .rustProposeTransferFromURI
|
||||
case .rustListAccounts: return .rustListAccounts
|
||||
case .rustIsSeedRelevantToWallet: return .rustIsSeedRelevantToWallet
|
||||
case .accountDAOGetAll: return .accountDAOGetAll
|
||||
case .accountDAOGetAllCantDecode: return .accountDAOGetAllCantDecode
|
||||
case .accountDAOFindBy: return .accountDAOFindBy
|
||||
|
|
|
@ -179,6 +179,8 @@ public enum ZcashErrorCode: String {
|
|||
case rustProposeTransferFromURI = "ZRUST0057"
|
||||
/// Error from rust layer when calling ZcashRustBackend.
|
||||
case rustListAccounts = "ZRUST0058"
|
||||
/// Error from rust layer when calling ZcashRustBackend.isSeedRelevantToWallet
|
||||
case rustIsSeedRelevantToWallet = "ZRUST0059"
|
||||
/// SQLite query failed when fetching all accounts from the database.
|
||||
case accountDAOGetAll = "ZADAO0001"
|
||||
/// Fetched accounts from SQLite but can't decode them.
|
||||
|
|
|
@ -356,6 +356,10 @@ enum ZcashErrorDefinition {
|
|||
/// - `rustError` contains error generated by the rust layer.
|
||||
// sourcery: code="ZRUST0058"
|
||||
case rustListAccounts(_ rustError: String)
|
||||
/// Error from rust layer when calling ZcashRustBackend.isSeedRelevantToWallet
|
||||
/// - `rustError` contains error generated by the rust layer.
|
||||
// sourcery: code="ZRUST0059"
|
||||
case rustIsSeedRelevantToWallet(_ rustError: String)
|
||||
|
||||
// MARK: - Account DAO
|
||||
|
||||
|
|
|
@ -276,6 +276,10 @@ extension LightWalletGRPCService: LightWalletService {
|
|||
}
|
||||
}
|
||||
|
||||
func getTreeState(_ id: BlockID) async throws -> TreeState {
|
||||
try await compactTxStreamer.getTreeState(id)
|
||||
}
|
||||
|
||||
func closeConnection() {
|
||||
_ = channel.close()
|
||||
}
|
||||
|
|
|
@ -196,4 +196,6 @@ protocol LightWalletService: AnyObject {
|
|||
/// - Parameters:
|
||||
/// - request: Request to send to GetSubtreeRoots.
|
||||
func getSubtreeRoots(_ request: GetSubtreeRootsArg) -> AsyncThrowingStream<SubtreeRoot, Error>
|
||||
|
||||
func getTreeState(_ id: BlockID) async throws -> TreeState
|
||||
}
|
||||
|
|
|
@ -105,6 +105,26 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return ffiBinaryKeyPtr.pointee.unsafeToUnifiedSpendingKey(network: networkType)
|
||||
}
|
||||
|
||||
func isSeedRelevantToWallet(seed: [UInt8]) async throws -> Bool {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_is_seed_relevant_to_wallet(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
seed,
|
||||
UInt(seed.count),
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
// -1 is the error sentinel.
|
||||
guard result >= 0 else {
|
||||
throw ZcashError.rustIsSeedRelevantToWallet(lastErrorMessage(fallback: "`isSeedRelevantToWallet` failed with unknown error"))
|
||||
}
|
||||
|
||||
// 0 is false, 1 is true.
|
||||
return result != 0
|
||||
}
|
||||
|
||||
func proposeTransfer(
|
||||
account: Int32,
|
||||
to address: String,
|
||||
|
@ -648,9 +668,20 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return scanRanges
|
||||
}
|
||||
|
||||
func scanBlocks(fromHeight: Int32, limit: UInt32 = 0) async throws -> ScanSummary {
|
||||
func scanBlocks(fromHeight: Int32, fromState: TreeState, limit: UInt32 = 0) async throws -> ScanSummary {
|
||||
let fromStateBytes = try fromState.serializedData(partial: false).bytes
|
||||
|
||||
globalDBLock.lock()
|
||||
let summaryPtr = zcashlc_scan_blocks(fsBlockDbRoot.0, fsBlockDbRoot.1, dbData.0, dbData.1, fromHeight, limit, networkType.networkId)
|
||||
let summaryPtr = zcashlc_scan_blocks(
|
||||
fsBlockDbRoot.0,
|
||||
fsBlockDbRoot.1,
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
fromHeight,
|
||||
fromStateBytes,
|
||||
UInt(fromStateBytes.count),
|
||||
limit,
|
||||
networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let summaryPtr else {
|
||||
|
@ -881,6 +912,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] {
|
||||
|
|
|
@ -44,6 +44,11 @@ protocol ZcashRustBackendWelding {
|
|||
/// - Throws: `rustCreateAccount`.
|
||||
func createAccount(seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?) async throws -> UnifiedSpendingKey
|
||||
|
||||
/// Checks whether the given seed is relevant to any of the accounts in the wallet.
|
||||
///
|
||||
/// - parameter seed: byte array of the seed
|
||||
func isSeedRelevantToWallet(seed: [UInt8]) async throws -> Bool
|
||||
|
||||
/// Scans a transaction for any information that can be decrypted by the accounts in the wallet, and saves it to the wallet.
|
||||
/// - parameter tx: the transaction to decrypt
|
||||
/// - parameter minedHeight: height on which this transaction was mined. this is used to fetch the consensus branch ID.
|
||||
|
@ -176,9 +181,10 @@ protocol ZcashRustBackendWelding {
|
|||
/// cache, an error will be signalled.
|
||||
///
|
||||
/// - parameter fromHeight: scan starting from the given height.
|
||||
/// - parameter fromState: The TreeState Protobuf object for the height prior to `fromHeight`
|
||||
/// - parameter limit: scan up to limit blocks.
|
||||
/// - Throws: `rustScanBlocks` if rust layer returns error.
|
||||
func scanBlocks(fromHeight: Int32, limit: UInt32) async throws -> ScanSummary
|
||||
func scanBlocks(fromHeight: Int32, fromState: TreeState, limit: UInt32) async throws -> ScanSummary
|
||||
|
||||
/// Upserts a UTXO into the data db database
|
||||
/// - parameter txid: the txid bytes for the UTXO
|
||||
|
|
|
@ -119,6 +119,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)
|
||||
|
@ -132,6 +133,7 @@ enum Dependencies {
|
|||
return BlockScannerImpl(
|
||||
config: blockScannerConfig,
|
||||
rustBackend: rustBackend,
|
||||
service: service,
|
||||
transactionRepository: transactionRepository,
|
||||
metrics: metrics,
|
||||
logger: logger
|
||||
|
|
|
@ -190,6 +190,10 @@ class DarksideWalletService: LightWalletService {
|
|||
func getSubtreeRoots(_ request: ZcashLightClientKit.GetSubtreeRootsArg) -> AsyncThrowingStream<ZcashLightClientKit.SubtreeRoot, Error> {
|
||||
service.getSubtreeRoots(request)
|
||||
}
|
||||
|
||||
func getTreeState(_ id: BlockID) async throws -> TreeState {
|
||||
try await service.getTreeState(id)
|
||||
}
|
||||
}
|
||||
|
||||
enum DarksideWalletDConstants: NetworkConstants {
|
||||
|
|
|
@ -82,4 +82,8 @@ class MockLightWalletService: LightWalletService {
|
|||
func getSubtreeRoots(_ request: ZcashLightClientKit.GetSubtreeRootsArg) -> AsyncThrowingStream<ZcashLightClientKit.SubtreeRoot, Error> {
|
||||
service.getSubtreeRoots(request)
|
||||
}
|
||||
|
||||
func getTreeState(_ id: BlockID) async throws -> TreeState {
|
||||
try await service.getTreeState(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
@ -2277,6 +2301,39 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - isSeedRelevantToWallet
|
||||
|
||||
var isSeedRelevantToWalletSeedThrowableError: Error?
|
||||
func setIsSeedRelevantToWalletSeedThrowableError(_ param: Error?) async {
|
||||
isSeedRelevantToWalletSeedThrowableError = param
|
||||
}
|
||||
var isSeedRelevantToWalletSeedCallsCount = 0
|
||||
var isSeedRelevantToWalletSeedCalled: Bool {
|
||||
return isSeedRelevantToWalletSeedCallsCount > 0
|
||||
}
|
||||
var isSeedRelevantToWalletSeedReceivedSeed: [UInt8]?
|
||||
var isSeedRelevantToWalletSeedReturnValue: Bool!
|
||||
func setIsSeedRelevantToWalletSeedReturnValue(_ param: Bool) async {
|
||||
isSeedRelevantToWalletSeedReturnValue = param
|
||||
}
|
||||
var isSeedRelevantToWalletSeedClosure: (([UInt8]) async throws -> Bool)?
|
||||
func setIsSeedRelevantToWalletSeedClosure(_ param: (([UInt8]) async throws -> Bool)?) async {
|
||||
isSeedRelevantToWalletSeedClosure = param
|
||||
}
|
||||
|
||||
func isSeedRelevantToWallet(seed: [UInt8]) async throws -> Bool {
|
||||
if let error = isSeedRelevantToWalletSeedThrowableError {
|
||||
throw error
|
||||
}
|
||||
isSeedRelevantToWalletSeedCallsCount += 1
|
||||
isSeedRelevantToWalletSeedReceivedSeed = seed
|
||||
if let closure = isSeedRelevantToWalletSeedClosure {
|
||||
return try await closure(seed)
|
||||
} else {
|
||||
return isSeedRelevantToWalletSeedReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - decryptAndStoreTransaction
|
||||
|
||||
var decryptAndStoreTransactionTxBytesMinedHeightThrowableError: Error?
|
||||
|
@ -2792,34 +2849,34 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
|
||||
// MARK: - scanBlocks
|
||||
|
||||
var scanBlocksFromHeightLimitThrowableError: Error?
|
||||
func setScanBlocksFromHeightLimitThrowableError(_ param: Error?) async {
|
||||
scanBlocksFromHeightLimitThrowableError = param
|
||||
var scanBlocksFromHeightFromStateLimitThrowableError: Error?
|
||||
func setScanBlocksFromHeightFromStateLimitThrowableError(_ param: Error?) async {
|
||||
scanBlocksFromHeightFromStateLimitThrowableError = param
|
||||
}
|
||||
var scanBlocksFromHeightLimitCallsCount = 0
|
||||
var scanBlocksFromHeightLimitCalled: Bool {
|
||||
return scanBlocksFromHeightLimitCallsCount > 0
|
||||
var scanBlocksFromHeightFromStateLimitCallsCount = 0
|
||||
var scanBlocksFromHeightFromStateLimitCalled: Bool {
|
||||
return scanBlocksFromHeightFromStateLimitCallsCount > 0
|
||||
}
|
||||
var scanBlocksFromHeightLimitReceivedArguments: (fromHeight: Int32, limit: UInt32)?
|
||||
var scanBlocksFromHeightLimitReturnValue: ScanSummary!
|
||||
func setScanBlocksFromHeightLimitReturnValue(_ param: ScanSummary) async {
|
||||
scanBlocksFromHeightLimitReturnValue = param
|
||||
var scanBlocksFromHeightFromStateLimitReceivedArguments: (fromHeight: Int32, fromState: TreeState, limit: UInt32)?
|
||||
var scanBlocksFromHeightFromStateLimitReturnValue: ScanSummary!
|
||||
func setScanBlocksFromHeightFromStateLimitReturnValue(_ param: ScanSummary) async {
|
||||
scanBlocksFromHeightFromStateLimitReturnValue = param
|
||||
}
|
||||
var scanBlocksFromHeightLimitClosure: ((Int32, UInt32) async throws -> ScanSummary)?
|
||||
func setScanBlocksFromHeightLimitClosure(_ param: ((Int32, UInt32) async throws -> ScanSummary)?) async {
|
||||
scanBlocksFromHeightLimitClosure = param
|
||||
var scanBlocksFromHeightFromStateLimitClosure: ((Int32, TreeState, UInt32) async throws -> ScanSummary)?
|
||||
func setScanBlocksFromHeightFromStateLimitClosure(_ param: ((Int32, TreeState, UInt32) async throws -> ScanSummary)?) async {
|
||||
scanBlocksFromHeightFromStateLimitClosure = param
|
||||
}
|
||||
|
||||
func scanBlocks(fromHeight: Int32, limit: UInt32) async throws -> ScanSummary {
|
||||
if let error = scanBlocksFromHeightLimitThrowableError {
|
||||
func scanBlocks(fromHeight: Int32, fromState: TreeState, limit: UInt32) async throws -> ScanSummary {
|
||||
if let error = scanBlocksFromHeightFromStateLimitThrowableError {
|
||||
throw error
|
||||
}
|
||||
scanBlocksFromHeightLimitCallsCount += 1
|
||||
scanBlocksFromHeightLimitReceivedArguments = (fromHeight: fromHeight, limit: limit)
|
||||
if let closure = scanBlocksFromHeightLimitClosure {
|
||||
return try await closure(fromHeight, limit)
|
||||
scanBlocksFromHeightFromStateLimitCallsCount += 1
|
||||
scanBlocksFromHeightFromStateLimitReceivedArguments = (fromHeight: fromHeight, fromState: fromState, limit: limit)
|
||||
if let closure = scanBlocksFromHeightFromStateLimitClosure {
|
||||
return try await closure(fromHeight, fromState, limit)
|
||||
} else {
|
||||
return scanBlocksFromHeightLimitReturnValue
|
||||
return scanBlocksFromHeightFromStateLimitReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue