Compare commits
2 Commits
8fa86ff37f
...
652bacd3d8
Author | SHA1 | Date |
---|---|---|
Lukas Korba | 652bacd3d8 | |
Lukas Korba | 3429afa9dc |
|
@ -8,22 +8,6 @@
|
|||
import Foundation
|
||||
import SQLite
|
||||
|
||||
extension Connection {
|
||||
public func scalarLocked<V: Value>(_ query: ScalarQuery<V?>) throws -> V.ValueType? {
|
||||
globalDBLock.lock()
|
||||
defer { globalDBLock.unlock() }
|
||||
|
||||
return try scalar(query)
|
||||
}
|
||||
|
||||
public func scalarLocked<V: Value>(_ query: ScalarQuery<V>) throws -> V {
|
||||
globalDBLock.lock()
|
||||
defer { globalDBLock.unlock() }
|
||||
|
||||
return try scalar(query)
|
||||
}
|
||||
}
|
||||
|
||||
class TransactionSQLDAO: TransactionRepository {
|
||||
enum NotesTableStructure {
|
||||
static let transactionID = Expression<Int>("tx")
|
||||
|
@ -55,17 +39,19 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
true
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func countAll() async throws -> Int {
|
||||
do {
|
||||
return try connection().scalarLocked(transactionsView.count)
|
||||
return try connection().scalar(transactionsView.count)
|
||||
} catch {
|
||||
throw ZcashError.transactionRepositoryCountAll(error)
|
||||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func countUnmined() async throws -> Int {
|
||||
do {
|
||||
return try connection().scalarLocked(transactionsView.filter(ZcashTransaction.Overview.Column.minedHeight == nil).count)
|
||||
return try connection().scalar(transactionsView.filter(ZcashTransaction.Overview.Column.minedHeight == nil).count)
|
||||
} catch {
|
||||
throw ZcashError.transactionRepositoryCountUnmined(error)
|
||||
}
|
||||
|
@ -76,7 +62,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.filter(ZcashTransaction.Overview.Column.rawID == Blob(bytes: rawID.bytes))
|
||||
.limit(1)
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
}
|
||||
|
||||
func find(offset: Int, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
|
||||
|
@ -85,7 +71,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.filterQueryFor(kind: kind)
|
||||
.limit(limit, offset: offset)
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
}
|
||||
|
||||
func find(in range: CompactBlockRange, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
|
||||
|
@ -98,7 +84,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.filterQueryFor(kind: kind)
|
||||
.limit(limit)
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
}
|
||||
|
||||
func find(from transaction: ZcashTransaction.Overview, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
|
||||
|
@ -119,7 +105,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.filterQueryFor(kind: kind)
|
||||
.limit(limit)
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
}
|
||||
|
||||
func findReceived(offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
|
||||
|
@ -128,7 +114,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
||||
.limit(limit, offset: offset)
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
}
|
||||
|
||||
func findSent(offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
|
||||
|
@ -137,7 +123,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
||||
.limit(limit, offset: offset)
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
}
|
||||
|
||||
func findPendingTransactions(latestHeight: BlockHeight, offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
|
||||
|
@ -146,7 +132,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
||||
.limit(limit, offset: offset)
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Overview(row: $0) }
|
||||
}
|
||||
|
||||
func findMemos(for transaction: ZcashTransaction.Overview) async throws -> [Memo] {
|
||||
|
@ -162,23 +148,25 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
let query = self.txOutputsView
|
||||
.filter(ZcashTransaction.Output.Column.rawID == Blob(bytes: rawID.bytes))
|
||||
|
||||
return try execute(query) { try ZcashTransaction.Output(row: $0) }
|
||||
return try await execute(query) { try ZcashTransaction.Output(row: $0) }
|
||||
}
|
||||
|
||||
func getRecipients(for rawID: Data) async throws -> [TransactionRecipient] {
|
||||
try await getTransactionOutputs(for: rawID).map { $0.recipient }
|
||||
}
|
||||
|
||||
private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) throws -> Entity {
|
||||
let entities: [Entity] = try execute(query, createEntity: createEntity)
|
||||
guard let entity = entities.first else { throw ZcashError.transactionRepositoryEntityNotFound }
|
||||
private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) async throws -> Entity {
|
||||
let entities: [Entity] = try await execute(query, createEntity: createEntity)
|
||||
|
||||
guard let entity = entities.first else {
|
||||
throw ZcashError.transactionRepositoryEntityNotFound
|
||||
}
|
||||
|
||||
return entity
|
||||
}
|
||||
|
||||
private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) throws -> [Entity] {
|
||||
globalDBLock.lock()
|
||||
defer { globalDBLock.unlock() }
|
||||
|
||||
@DBActor
|
||||
private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) async throws -> [Entity] {
|
||||
do {
|
||||
let entities = try connection()
|
||||
.prepare(query)
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
import Foundation
|
||||
import libzcashlc
|
||||
|
||||
let globalDBLock = NSLock()
|
||||
|
||||
actor ZcashRustBackend: ZcashRustBackendWelding {
|
||||
struct ZcashRustBackend: ZcashRustBackendWelding {
|
||||
let minimumConfirmations: UInt32 = 10
|
||||
let useZIP317Fees = true
|
||||
|
||||
|
@ -21,7 +19,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
let outputParamsPath: (String, UInt)
|
||||
let keyDeriving: ZcashKeyDerivationBackendWelding
|
||||
|
||||
nonisolated let networkType: NetworkType
|
||||
let networkType: NetworkType
|
||||
|
||||
static var tracingEnabled = false
|
||||
/// Creates instance of `ZcashRustBackend`.
|
||||
|
@ -49,14 +47,13 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func listAccounts() async throws -> [Int32] {
|
||||
globalDBLock.lock()
|
||||
let accountsPtr = zcashlc_list_accounts(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let accountsPtr else {
|
||||
throw ZcashError.rustListAccounts(lastErrorMessage(fallback: "`listAccounts` failed with unknown error"))
|
||||
|
@ -74,6 +71,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return accounts
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func createAccount(seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?) async throws -> UnifiedSpendingKey {
|
||||
var rUntil: Int64 = -1
|
||||
|
||||
|
@ -83,7 +81,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
|
||||
let treeStateBytes = try treeState.serializedData(partial: false).bytes
|
||||
|
||||
globalDBLock.lock()
|
||||
let ffiBinaryKeyPtr = zcashlc_create_account(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -94,7 +91,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
rUntil,
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let ffiBinaryKeyPtr else {
|
||||
throw ZcashError.rustCreateAccount(lastErrorMessage(fallback: "`createAccount` failed with unknown error"))
|
||||
|
@ -105,8 +101,8 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return ffiBinaryKeyPtr.pointee.unsafeToUnifiedSpendingKey(network: networkType)
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func isSeedRelevantToAnyDerivedAccount(seed: [UInt8]) async throws -> Bool {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_is_seed_relevant_to_any_derived_account(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -114,7 +110,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
UInt(seed.count),
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
// -1 is the error sentinel.
|
||||
guard result >= 0 else {
|
||||
|
@ -125,13 +120,13 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return result != 0
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func proposeTransfer(
|
||||
account: Int32,
|
||||
to address: String,
|
||||
value: Int64,
|
||||
memo: MemoBytes?
|
||||
) async throws -> FfiProposal {
|
||||
globalDBLock.lock()
|
||||
let proposal = zcashlc_propose_transfer(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -143,7 +138,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
minimumConfirmations,
|
||||
useZIP317Fees
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let proposal else {
|
||||
throw ZcashError.rustCreateToAddress(lastErrorMessage(fallback: "`proposeTransfer` failed with unknown error"))
|
||||
|
@ -157,11 +151,11 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
))
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func proposeTransferFromURI(
|
||||
_ uri: String,
|
||||
account: Int32
|
||||
) async throws -> FfiProposal {
|
||||
globalDBLock.lock()
|
||||
let proposal = zcashlc_propose_transfer_from_uri(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -171,7 +165,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
minimumConfirmations,
|
||||
useZIP317Fees
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let proposal else {
|
||||
throw ZcashError.rustCreateToAddress(lastErrorMessage(fallback: "`proposeTransfer` failed with unknown error"))
|
||||
|
@ -185,8 +178,8 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
))
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func decryptAndStoreTransaction(txBytes: [UInt8], minedHeight: Int32) async throws {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_decrypt_and_store_transaction(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -195,22 +188,20 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
UInt32(minedHeight),
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard result != 0 else {
|
||||
throw ZcashError.rustDecryptAndStoreTransaction(lastErrorMessage(fallback: "`decryptAndStoreTransaction` failed with unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func getCurrentAddress(account: Int32) async throws -> UnifiedAddress {
|
||||
globalDBLock.lock()
|
||||
let addressCStr = zcashlc_get_current_address(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
account,
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let addressCStr else {
|
||||
throw ZcashError.rustGetCurrentAddress(lastErrorMessage(fallback: "`getCurrentAddress` failed with unknown error"))
|
||||
|
@ -225,15 +216,14 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return UnifiedAddress(validatedEncoding: address, networkType: networkType)
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func getNearestRewindHeight(height: Int32) async throws -> Int32 {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_get_nearest_rewind_height(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
height,
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard result > 0 else {
|
||||
throw ZcashError.rustGetNearestRewindHeight(lastErrorMessage(fallback: "`getNearestRewindHeight` failed with unknown error"))
|
||||
|
@ -242,15 +232,14 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return result
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func getNextAvailableAddress(account: Int32) async throws -> UnifiedAddress {
|
||||
globalDBLock.lock()
|
||||
let addressCStr = zcashlc_get_next_available_address(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
account,
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let addressCStr else {
|
||||
throw ZcashError.rustGetNextAvailableAddress(lastErrorMessage(fallback: "`getNextAvailableAddress` failed with unknown error"))
|
||||
|
@ -265,6 +254,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return UnifiedAddress(validatedEncoding: address, networkType: networkType)
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func getMemo(txId: Data, outputIndex: UInt16) async throws -> Memo? {
|
||||
guard txId.count == 32 else {
|
||||
throw ZcashError.rustGetMemoInvalidTxIdLength
|
||||
|
@ -273,30 +263,27 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
var contiguousMemoBytes = ContiguousArray<UInt8>(MemoBytes.empty().bytes)
|
||||
var success = false
|
||||
|
||||
globalDBLock.lock()
|
||||
contiguousMemoBytes.withUnsafeMutableBufferPointer { memoBytePtr in
|
||||
success = zcashlc_get_memo(dbData.0, dbData.1, txId.bytes, outputIndex, memoBytePtr.baseAddress, networkType.networkId)
|
||||
}
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard success else { return nil }
|
||||
|
||||
return (try? MemoBytes(contiguousBytes: contiguousMemoBytes)).flatMap { try? $0.intoMemo() }
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func getTransparentBalance(account: Int32) async throws -> Int64 {
|
||||
guard account >= 0 else {
|
||||
throw ZcashError.rustGetTransparentBalanceNegativeAccount(Int(account))
|
||||
}
|
||||
|
||||
globalDBLock.lock()
|
||||
let balance = zcashlc_get_total_transparent_balance_for_account(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
networkType.networkId,
|
||||
account
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard balance >= 0 else {
|
||||
throw ZcashError.rustGetTransparentBalance(
|
||||
|
@ -308,12 +295,12 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return balance
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func getVerifiedTransparentBalance(account: Int32) async throws -> Int64 {
|
||||
guard account >= 0 else {
|
||||
throw ZcashError.rustGetVerifiedTransparentBalanceNegativeAccount(Int(account))
|
||||
}
|
||||
|
||||
globalDBLock.lock()
|
||||
let balance = zcashlc_get_verified_transparent_balance_for_account(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -321,7 +308,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
account,
|
||||
minimumConfirmations
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard balance >= 0 else {
|
||||
throw ZcashError.rustGetVerifiedTransparentBalance(
|
||||
|
@ -333,10 +319,9 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return balance
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func initDataDb(seed: [UInt8]?) async throws -> DbInitResult {
|
||||
globalDBLock.lock()
|
||||
let initResult = zcashlc_init_data_database(dbData.0, dbData.1, seed, UInt(seed?.count ?? 0), networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
switch initResult {
|
||||
case 0: // ok
|
||||
|
@ -350,16 +335,16 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func initBlockMetadataDb() async throws {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_init_block_metadata_db(fsBlockDbRoot.0, fsBlockDbRoot.1)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard result else {
|
||||
throw ZcashError.rustInitBlockMetadataDb(lastErrorMessage(fallback: "`initBlockMetadataDb` failed with unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func writeBlocksMetadata(blocks: [ZcashCompactBlock]) async throws {
|
||||
var ffiBlockMetaVec: [FFIBlockMeta] = []
|
||||
|
||||
|
@ -409,9 +394,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
|
||||
fsBlocks.initialize(to: meta)
|
||||
|
||||
globalDBLock.lock()
|
||||
let res = zcashlc_write_block_metadata(fsBlockDbRoot.0, fsBlockDbRoot.1, fsBlocks)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard res else {
|
||||
throw ZcashError.rustWriteBlocksMetadata(lastErrorMessage(fallback: "`writeBlocksMetadata` failed with unknown error"))
|
||||
|
@ -419,10 +402,9 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func latestCachedBlockHeight() async throws -> BlockHeight {
|
||||
globalDBLock.lock()
|
||||
let height = zcashlc_latest_cached_block_height(fsBlockDbRoot.0, fsBlockDbRoot.1)
|
||||
globalDBLock.unlock()
|
||||
|
||||
if height >= 0 {
|
||||
return BlockHeight(height)
|
||||
|
@ -433,15 +415,14 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func listTransparentReceivers(account: Int32) async throws -> [TransparentAddress] {
|
||||
globalDBLock.lock()
|
||||
let encodedKeysPtr = zcashlc_list_transparent_receivers(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
account,
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let encodedKeysPtr else {
|
||||
throw ZcashError.rustListTransparentReceivers(lastErrorMessage(fallback: "`listTransparentReceivers` failed with unknown error"))
|
||||
|
@ -466,6 +447,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return addresses
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func putUnspentTransparentOutput(
|
||||
txid: [UInt8],
|
||||
index: Int,
|
||||
|
@ -473,7 +455,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
value: Int64,
|
||||
height: BlockHeight
|
||||
) async throws {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_put_utxo(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -486,33 +467,31 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
Int32(height),
|
||||
networkType.networkId
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard result else {
|
||||
throw ZcashError.rustPutUnspentTransparentOutput(lastErrorMessage(fallback: "`putUnspentTransparentOutput` failed with unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func rewindToHeight(height: Int32) async throws {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_rewind_to_height(dbData.0, dbData.1, height, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard result else {
|
||||
throw ZcashError.rustRewindToHeight(height, lastErrorMessage(fallback: "`rewindToHeight` failed with unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func rewindCacheToHeight(height: Int32) async throws {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_rewind_fs_block_cache_to_height(fsBlockDbRoot.0, fsBlockDbRoot.1, height)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard result else {
|
||||
throw ZcashError.rustRewindCacheToHeight(lastErrorMessage(fallback: "`rewindCacheToHeight` failed with unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func putSaplingSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
|
||||
var ffiSubtreeRootsVec: [FfiSubtreeRoot] = []
|
||||
|
||||
|
@ -561,9 +540,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
|
||||
rootsPtr.initialize(to: roots)
|
||||
|
||||
globalDBLock.lock()
|
||||
let res = zcashlc_put_sapling_subtree_roots(dbData.0, dbData.1, startIndex, rootsPtr, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard res else {
|
||||
throw ZcashError.rustPutSaplingSubtreeRoots(lastErrorMessage(fallback: "`putSaplingSubtreeRoots` failed with unknown error"))
|
||||
|
@ -571,6 +548,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func putOrchardSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
|
||||
var ffiSubtreeRootsVec: [FfiSubtreeRoot] = []
|
||||
|
||||
|
@ -619,9 +597,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
|
||||
rootsPtr.initialize(to: roots)
|
||||
|
||||
globalDBLock.lock()
|
||||
let res = zcashlc_put_orchard_subtree_roots(dbData.0, dbData.1, startIndex, rootsPtr, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard res else {
|
||||
throw ZcashError.rustPutOrchardSubtreeRoots(lastErrorMessage(fallback: "`putOrchardSubtreeRoots` failed with unknown error"))
|
||||
|
@ -629,20 +605,18 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func updateChainTip(height: Int32) async throws {
|
||||
globalDBLock.lock()
|
||||
let result = zcashlc_update_chain_tip(dbData.0, dbData.1, height, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard result else {
|
||||
throw ZcashError.rustUpdateChainTip(lastErrorMessage(fallback: "`updateChainTip` failed with unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func fullyScannedHeight() async throws -> BlockHeight? {
|
||||
globalDBLock.lock()
|
||||
let height = zcashlc_fully_scanned_height(dbData.0, dbData.1, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
if height >= 0 {
|
||||
return BlockHeight(height)
|
||||
|
@ -653,10 +627,9 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func maxScannedHeight() async throws -> BlockHeight? {
|
||||
globalDBLock.lock()
|
||||
let height = zcashlc_max_scanned_height(dbData.0, dbData.1, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
if height >= 0 {
|
||||
return BlockHeight(height)
|
||||
|
@ -667,10 +640,9 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
}
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func getWalletSummary() async throws -> WalletSummary? {
|
||||
globalDBLock.lock()
|
||||
let summaryPtr = zcashlc_get_wallet_summary(dbData.0, dbData.1, networkType.networkId, minimumConfirmations)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let summaryPtr else {
|
||||
throw ZcashError.rustGetWalletSummary(lastErrorMessage(fallback: "`getWalletSummary` failed with unknown error"))
|
||||
|
@ -699,10 +671,9 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
)
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func suggestScanRanges() async throws -> [ScanRange] {
|
||||
globalDBLock.lock()
|
||||
let scanRangesPtr = zcashlc_suggest_scan_ranges(dbData.0, dbData.1, networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let scanRangesPtr else {
|
||||
throw ZcashError.rustSuggestScanRanges(lastErrorMessage(fallback: "`suggestScanRanges` failed with unknown error"))
|
||||
|
@ -729,10 +700,10 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
return scanRanges
|
||||
}
|
||||
|
||||
@DBActor
|
||||
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,
|
||||
|
@ -742,8 +713,8 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
fromStateBytes,
|
||||
UInt(fromStateBytes.count),
|
||||
limit,
|
||||
networkType.networkId)
|
||||
globalDBLock.unlock()
|
||||
networkType.networkId
|
||||
)
|
||||
|
||||
guard let summaryPtr else {
|
||||
throw ZcashError.rustScanBlocks(lastErrorMessage(fallback: "`scanBlocks` failed with unknown error"))
|
||||
|
@ -761,13 +732,13 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
)
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func proposeShielding(
|
||||
account: Int32,
|
||||
memo: MemoBytes?,
|
||||
shieldingThreshold: Zatoshi,
|
||||
transparentReceiver: String?
|
||||
) async throws -> FfiProposal? {
|
||||
globalDBLock.lock()
|
||||
let proposal = zcashlc_propose_shielding(
|
||||
dbData.0,
|
||||
dbData.1,
|
||||
|
@ -779,7 +750,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
minimumConfirmations,
|
||||
useZIP317Fees
|
||||
)
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let proposal else {
|
||||
throw ZcashError.rustShieldFunds(lastErrorMessage(fallback: "`proposeShielding` failed with unknown error"))
|
||||
|
@ -793,13 +763,13 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
))
|
||||
}
|
||||
|
||||
@DBActor
|
||||
func createProposedTransactions(
|
||||
proposal: FfiProposal,
|
||||
usk: UnifiedSpendingKey
|
||||
) async throws -> [Data] {
|
||||
let proposalBytes = try proposal.serializedData(partial: false).bytes
|
||||
|
||||
globalDBLock.lock()
|
||||
let txIdsPtr = proposalBytes.withUnsafeBufferPointer { proposalPtr in
|
||||
usk.bytes.withUnsafeBufferPointer { uskPtr in
|
||||
zcashlc_create_proposed_transactions(
|
||||
|
@ -817,7 +787,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
|
|||
)
|
||||
}
|
||||
}
|
||||
globalDBLock.unlock()
|
||||
|
||||
guard let txIdsPtr else {
|
||||
throw ZcashError.rustCreateToAddress(lastErrorMessage(fallback: "`createToAddress` failed with unknown error"))
|
||||
|
|
|
@ -21,7 +21,6 @@ public enum DbInitResult {
|
|||
case seedNotRelevant
|
||||
}
|
||||
|
||||
// sourcery: mockActor
|
||||
protocol ZcashRustBackendWelding {
|
||||
/// Returns a list of the accounts in the wallet.
|
||||
func listAccounts() async throws -> [Int32]
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// DBActor.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 04-08-2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Global actor used to protect access to the Data DB.
|
||||
@globalActor
|
||||
enum DBActor {
|
||||
typealias ActorType = Actor
|
||||
|
||||
actor Actor { }
|
||||
static let shared = Actor()
|
||||
|
||||
static var sharedUnownedExecutor: UnownedSerialExecutor {
|
||||
shared.unownedExecutor
|
||||
}
|
||||
}
|
|
@ -104,8 +104,8 @@ class CompactBlockReorgTests: ZcashTestCase {
|
|||
loggingPolicy: .default(.debug)
|
||||
)
|
||||
|
||||
await self.rustBackendMockHelper.rustBackendMock.setPutSaplingSubtreeRootsStartIndexRootsClosure { _, _ in }
|
||||
await self.rustBackendMockHelper.rustBackendMock.setUpdateChainTipHeightClosure { _ in }
|
||||
self.rustBackendMockHelper.rustBackendMock.putSaplingSubtreeRootsStartIndexRootsClosure = { _, _ in }
|
||||
self.rustBackendMockHelper.rustBackendMock.updateChainTipHeightClosure = { _ in }
|
||||
|
||||
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { [self] _ in
|
||||
LatestBlocksDataProviderImpl(service: service, rustBackend: self.rustBackend)
|
||||
|
|
|
@ -31,7 +31,7 @@ final class ProcessSuggestedScanRangesActionTests: ZcashTestCase {
|
|||
loggerMock.syncFileFunctionLineClosure = { _, _, _, _ in }
|
||||
|
||||
let tupple = setupAction(loggerMock)
|
||||
await tupple.rustBackendMock.setSuggestScanRangesClosure({ [] })
|
||||
tupple.rustBackendMock.suggestScanRangesClosure = { [] }
|
||||
|
||||
let processSuggestedScanRangesActionAction = tupple.action
|
||||
|
||||
|
@ -59,9 +59,9 @@ final class ProcessSuggestedScanRangesActionTests: ZcashTestCase {
|
|||
sdkMetricsMock.actionDetailForClosure = { _, _ in }
|
||||
|
||||
let tupple = setupAction(loggerMock, sdkMetricsMock)
|
||||
await tupple.rustBackendMock.setSuggestScanRangesClosure({ [
|
||||
ScanRange(range: 0..<10, priority: .chainTip)
|
||||
] })
|
||||
tupple.rustBackendMock.suggestScanRangesClosure = {
|
||||
[ScanRange(range: 0..<10, priority: .chainTip)]
|
||||
}
|
||||
|
||||
let processSuggestedScanRangesActionAction = tupple.action
|
||||
|
||||
|
@ -121,12 +121,11 @@ final class ProcessSuggestedScanRangesActionTests: ZcashTestCase {
|
|||
for: ZcashNetworkBuilder.network(for: underlyingNetworkType), walletBirthday: 0
|
||||
)
|
||||
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock(
|
||||
consensusBranchIdForHeightClosure: { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
)
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock()
|
||||
rustBackendMock.consensusBranchIdForHeightClosure = { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
|
||||
let lightWalletdInfoMock = LightWalletdInfoMock()
|
||||
lightWalletdInfoMock.underlyingConsensusBranchID = underlyingConsensusBranchID
|
||||
|
|
|
@ -92,14 +92,14 @@ final class RewindActionTests: ZcashTestCase {
|
|||
_ loggerMock: LoggerMock = LoggerMock(),
|
||||
_ blockDownloaderServiceMock: BlockDownloaderServiceMock = BlockDownloaderServiceMock()
|
||||
) async -> RewindAction {
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock(
|
||||
consensusBranchIdForHeightClosure: { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
)
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock()
|
||||
|
||||
await rustBackendMock.setRewindToHeightHeightClosure({ _ in })
|
||||
rustBackendMock.consensusBranchIdForHeightClosure = { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
|
||||
rustBackendMock.rewindToHeightHeightClosure = { _ in }
|
||||
|
||||
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in rustBackendMock }
|
||||
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in blockDownloaderServiceMock }
|
||||
|
|
|
@ -136,12 +136,12 @@ final class ScanActionTests: ZcashTestCase {
|
|||
_ loggerMock: LoggerMock,
|
||||
_ latestBlocksDataProvider: LatestBlocksDataProvider = LatestBlocksDataProviderMock()
|
||||
) -> ScanAction {
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock(
|
||||
consensusBranchIdForHeightClosure: { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
)
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock()
|
||||
|
||||
rustBackendMock.consensusBranchIdForHeightClosure = { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
|
||||
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in rustBackendMock }
|
||||
mockContainer.mock(type: BlockScanner.self, isSingleton: true) { _ in blockScannerMock }
|
||||
|
|
|
@ -115,14 +115,14 @@ final class UpdateChainTipActionTests: ZcashTestCase {
|
|||
for: ZcashNetworkBuilder.network(for: underlyingNetworkType), walletBirthday: 0
|
||||
)
|
||||
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock(
|
||||
consensusBranchIdForHeightClosure: { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
)
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock()
|
||||
|
||||
await rustBackendMock.setUpdateChainTipHeightClosure({ _ in })
|
||||
rustBackendMock.consensusBranchIdForHeightClosure = { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
|
||||
rustBackendMock.updateChainTipHeightClosure = { _ in }
|
||||
|
||||
let lightWalletdInfoMock = LightWalletdInfoMock()
|
||||
lightWalletdInfoMock.underlyingConsensusBranchID = underlyingConsensusBranchID
|
||||
|
|
|
@ -69,8 +69,9 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
continuation.finish()
|
||||
}
|
||||
}
|
||||
await tupple.rustBackendMock.setPutSaplingSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
await tupple.rustBackendMock.setPutOrchardSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
|
||||
tupple.rustBackendMock.putSaplingSubtreeRootsStartIndexRootsClosure = { _, _ in }
|
||||
tupple.rustBackendMock.putOrchardSubtreeRootsStartIndexRootsClosure = { _, _ in }
|
||||
|
||||
do {
|
||||
let context = ActionContextMock.default()
|
||||
|
@ -98,8 +99,9 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
continuation.finish()
|
||||
}
|
||||
}
|
||||
await tupple.rustBackendMock.setPutSaplingSubtreeRootsStartIndexRootsThrowableError("putSaplingFailed")
|
||||
await tupple.rustBackendMock.setPutOrchardSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
|
||||
tupple.rustBackendMock.putSaplingSubtreeRootsStartIndexRootsThrowableError = "putSaplingFailed"
|
||||
tupple.rustBackendMock.putOrchardSubtreeRootsStartIndexRootsClosure = { _, _ in }
|
||||
|
||||
do {
|
||||
let context = ActionContextMock.default()
|
||||
|
@ -128,8 +130,9 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
continuation.finish()
|
||||
}
|
||||
}
|
||||
await tupple.rustBackendMock.setPutSaplingSubtreeRootsStartIndexRootsClosure({ _, _ in })
|
||||
await tupple.rustBackendMock.setPutOrchardSubtreeRootsStartIndexRootsThrowableError("putOrchardFailed")
|
||||
|
||||
tupple.rustBackendMock.putSaplingSubtreeRootsStartIndexRootsClosure = { _, _ in }
|
||||
tupple.rustBackendMock.putOrchardSubtreeRootsStartIndexRootsThrowableError = "putOrchardFailed"
|
||||
|
||||
do {
|
||||
let context = ActionContextMock.default()
|
||||
|
@ -156,12 +159,11 @@ final class UpdateSubtreeRootsActionTests: ZcashTestCase {
|
|||
for: ZcashNetworkBuilder.network(for: underlyingNetworkType), walletBirthday: 0
|
||||
)
|
||||
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock(
|
||||
consensusBranchIdForHeightClosure: { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
)
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock()
|
||||
rustBackendMock.consensusBranchIdForHeightClosure = { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
|
||||
let lightWalletdInfoMock = LightWalletdInfoMock()
|
||||
lightWalletdInfoMock.underlyingConsensusBranchID = underlyingConsensusBranchID
|
||||
|
|
|
@ -135,12 +135,11 @@ final class ValidateServerActionTests: ZcashTestCase {
|
|||
for: ZcashNetworkBuilder.network(for: underlyingNetworkType), walletBirthday: 0
|
||||
)
|
||||
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock(
|
||||
consensusBranchIdForHeightClosure: { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
)
|
||||
let rustBackendMock = ZcashRustBackendWeldingMock()
|
||||
rustBackendMock.consensusBranchIdForHeightClosure = { height in
|
||||
XCTAssertEqual(height, 2, "")
|
||||
return -1026109260
|
||||
}
|
||||
|
||||
let lightWalletdInfoMock = LightWalletdInfoMock()
|
||||
lightWalletdInfoMock.underlyingConsensusBranchID = underlyingConsensusBranchID
|
||||
|
|
|
@ -414,7 +414,8 @@ final class FsBlockStorageTests: ZcashTestCase {
|
|||
return
|
||||
}
|
||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend)
|
||||
await mockBackend.rustBackendMock.setWriteBlocksMetadataBlocksThrowableError(ZcashError.rustWriteBlocksMetadataAllocationProblem)
|
||||
|
||||
mockBackend.rustBackendMock.writeBlocksMetadataBlocksThrowableError = ZcashError.rustWriteBlocksMetadataAllocationProblem
|
||||
|
||||
do {
|
||||
try await FSMetadataStore.saveBlocksMeta(
|
||||
|
@ -434,7 +435,7 @@ final class FsBlockStorageTests: ZcashTestCase {
|
|||
let expectedHeight = BlockHeight(1000)
|
||||
|
||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend)
|
||||
await mockBackend.rustBackendMock.setRewindCacheToHeightHeightThrowableError(ZcashError.rustRewindToHeight(Int32(expectedHeight), "oops"))
|
||||
mockBackend.rustBackendMock.rewindCacheToHeightHeightThrowableError = ZcashError.rustRewindToHeight(Int32(expectedHeight), "oops")
|
||||
|
||||
do {
|
||||
try await FSMetadataStore.live(
|
||||
|
|
|
@ -2251,34 +2251,22 @@ class ZcashFileManagerMock: ZcashFileManager {
|
|||
}
|
||||
|
||||
}
|
||||
actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||
class ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
||||
|
||||
nonisolated let consensusBranchIdForHeightClosure: ((Int32) throws -> Int32)?
|
||||
|
||||
init(
|
||||
consensusBranchIdForHeightClosure: ((Int32) throws -> Int32)? = nil
|
||||
) {
|
||||
self.consensusBranchIdForHeightClosure = consensusBranchIdForHeightClosure
|
||||
}
|
||||
|
||||
// MARK: - listAccounts
|
||||
|
||||
var listAccountsThrowableError: Error?
|
||||
func setListAccountsThrowableError(_ param: Error?) async {
|
||||
listAccountsThrowableError = param
|
||||
}
|
||||
var listAccountsCallsCount = 0
|
||||
var listAccountsCalled: Bool {
|
||||
return listAccountsCallsCount > 0
|
||||
}
|
||||
var listAccountsReturnValue: [Int32]!
|
||||
func setListAccountsReturnValue(_ param: [Int32]) async {
|
||||
listAccountsReturnValue = param
|
||||
}
|
||||
var listAccountsClosure: (() async throws -> [Int32])?
|
||||
func setListAccountsClosure(_ param: (() async throws -> [Int32])?) async {
|
||||
listAccountsClosure = param
|
||||
}
|
||||
|
||||
func listAccounts() async throws -> [Int32] {
|
||||
if let error = listAccountsThrowableError {
|
||||
|
@ -2295,22 +2283,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - createAccount
|
||||
|
||||
var createAccountSeedTreeStateRecoverUntilThrowableError: Error?
|
||||
func setCreateAccountSeedTreeStateRecoverUntilThrowableError(_ param: Error?) async {
|
||||
createAccountSeedTreeStateRecoverUntilThrowableError = param
|
||||
}
|
||||
var createAccountSeedTreeStateRecoverUntilCallsCount = 0
|
||||
var createAccountSeedTreeStateRecoverUntilCalled: Bool {
|
||||
return createAccountSeedTreeStateRecoverUntilCallsCount > 0
|
||||
}
|
||||
var createAccountSeedTreeStateRecoverUntilReceivedArguments: (seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?)?
|
||||
var createAccountSeedTreeStateRecoverUntilReturnValue: UnifiedSpendingKey!
|
||||
func setCreateAccountSeedTreeStateRecoverUntilReturnValue(_ param: UnifiedSpendingKey) async {
|
||||
createAccountSeedTreeStateRecoverUntilReturnValue = param
|
||||
}
|
||||
var createAccountSeedTreeStateRecoverUntilClosure: (([UInt8], TreeState, UInt32?) async throws -> UnifiedSpendingKey)?
|
||||
func setCreateAccountSeedTreeStateRecoverUntilClosure(_ param: (([UInt8], TreeState, UInt32?) async throws -> UnifiedSpendingKey)?) async {
|
||||
createAccountSeedTreeStateRecoverUntilClosure = param
|
||||
}
|
||||
|
||||
func createAccount(seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?) async throws -> UnifiedSpendingKey {
|
||||
if let error = createAccountSeedTreeStateRecoverUntilThrowableError {
|
||||
|
@ -2328,22 +2307,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - isSeedRelevantToAnyDerivedAccount
|
||||
|
||||
var isSeedRelevantToAnyDerivedAccountSeedThrowableError: Error?
|
||||
func setIsSeedRelevantToAnyDerivedAccountSeedThrowableError(_ param: Error?) async {
|
||||
isSeedRelevantToAnyDerivedAccountSeedThrowableError = param
|
||||
}
|
||||
var isSeedRelevantToAnyDerivedAccountSeedCallsCount = 0
|
||||
var isSeedRelevantToAnyDerivedAccountSeedCalled: Bool {
|
||||
return isSeedRelevantToAnyDerivedAccountSeedCallsCount > 0
|
||||
}
|
||||
var isSeedRelevantToAnyDerivedAccountSeedReceivedSeed: [UInt8]?
|
||||
var isSeedRelevantToAnyDerivedAccountSeedReturnValue: Bool!
|
||||
func setIsSeedRelevantToAnyDerivedAccountSeedReturnValue(_ param: Bool) async {
|
||||
isSeedRelevantToAnyDerivedAccountSeedReturnValue = param
|
||||
}
|
||||
var isSeedRelevantToAnyDerivedAccountSeedClosure: (([UInt8]) async throws -> Bool)?
|
||||
func setIsSeedRelevantToAnyDerivedAccountSeedClosure(_ param: (([UInt8]) async throws -> Bool)?) async {
|
||||
isSeedRelevantToAnyDerivedAccountSeedClosure = param
|
||||
}
|
||||
|
||||
func isSeedRelevantToAnyDerivedAccount(seed: [UInt8]) async throws -> Bool {
|
||||
if let error = isSeedRelevantToAnyDerivedAccountSeedThrowableError {
|
||||
|
@ -2361,18 +2331,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - decryptAndStoreTransaction
|
||||
|
||||
var decryptAndStoreTransactionTxBytesMinedHeightThrowableError: Error?
|
||||
func setDecryptAndStoreTransactionTxBytesMinedHeightThrowableError(_ param: Error?) async {
|
||||
decryptAndStoreTransactionTxBytesMinedHeightThrowableError = param
|
||||
}
|
||||
var decryptAndStoreTransactionTxBytesMinedHeightCallsCount = 0
|
||||
var decryptAndStoreTransactionTxBytesMinedHeightCalled: Bool {
|
||||
return decryptAndStoreTransactionTxBytesMinedHeightCallsCount > 0
|
||||
}
|
||||
var decryptAndStoreTransactionTxBytesMinedHeightReceivedArguments: (txBytes: [UInt8], minedHeight: Int32)?
|
||||
var decryptAndStoreTransactionTxBytesMinedHeightClosure: (([UInt8], Int32) async throws -> Void)?
|
||||
func setDecryptAndStoreTransactionTxBytesMinedHeightClosure(_ param: (([UInt8], Int32) async throws -> Void)?) async {
|
||||
decryptAndStoreTransactionTxBytesMinedHeightClosure = param
|
||||
}
|
||||
|
||||
func decryptAndStoreTransaction(txBytes: [UInt8], minedHeight: Int32) async throws {
|
||||
if let error = decryptAndStoreTransactionTxBytesMinedHeightThrowableError {
|
||||
|
@ -2386,22 +2350,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - getCurrentAddress
|
||||
|
||||
var getCurrentAddressAccountThrowableError: Error?
|
||||
func setGetCurrentAddressAccountThrowableError(_ param: Error?) async {
|
||||
getCurrentAddressAccountThrowableError = param
|
||||
}
|
||||
var getCurrentAddressAccountCallsCount = 0
|
||||
var getCurrentAddressAccountCalled: Bool {
|
||||
return getCurrentAddressAccountCallsCount > 0
|
||||
}
|
||||
var getCurrentAddressAccountReceivedAccount: Int32?
|
||||
var getCurrentAddressAccountReturnValue: UnifiedAddress!
|
||||
func setGetCurrentAddressAccountReturnValue(_ param: UnifiedAddress) async {
|
||||
getCurrentAddressAccountReturnValue = param
|
||||
}
|
||||
var getCurrentAddressAccountClosure: ((Int32) async throws -> UnifiedAddress)?
|
||||
func setGetCurrentAddressAccountClosure(_ param: ((Int32) async throws -> UnifiedAddress)?) async {
|
||||
getCurrentAddressAccountClosure = param
|
||||
}
|
||||
|
||||
func getCurrentAddress(account: Int32) async throws -> UnifiedAddress {
|
||||
if let error = getCurrentAddressAccountThrowableError {
|
||||
|
@ -2419,22 +2374,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - getNearestRewindHeight
|
||||
|
||||
var getNearestRewindHeightHeightThrowableError: Error?
|
||||
func setGetNearestRewindHeightHeightThrowableError(_ param: Error?) async {
|
||||
getNearestRewindHeightHeightThrowableError = param
|
||||
}
|
||||
var getNearestRewindHeightHeightCallsCount = 0
|
||||
var getNearestRewindHeightHeightCalled: Bool {
|
||||
return getNearestRewindHeightHeightCallsCount > 0
|
||||
}
|
||||
var getNearestRewindHeightHeightReceivedHeight: Int32?
|
||||
var getNearestRewindHeightHeightReturnValue: Int32!
|
||||
func setGetNearestRewindHeightHeightReturnValue(_ param: Int32) async {
|
||||
getNearestRewindHeightHeightReturnValue = param
|
||||
}
|
||||
var getNearestRewindHeightHeightClosure: ((Int32) async throws -> Int32)?
|
||||
func setGetNearestRewindHeightHeightClosure(_ param: ((Int32) async throws -> Int32)?) async {
|
||||
getNearestRewindHeightHeightClosure = param
|
||||
}
|
||||
|
||||
func getNearestRewindHeight(height: Int32) async throws -> Int32 {
|
||||
if let error = getNearestRewindHeightHeightThrowableError {
|
||||
|
@ -2452,22 +2398,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - getNextAvailableAddress
|
||||
|
||||
var getNextAvailableAddressAccountThrowableError: Error?
|
||||
func setGetNextAvailableAddressAccountThrowableError(_ param: Error?) async {
|
||||
getNextAvailableAddressAccountThrowableError = param
|
||||
}
|
||||
var getNextAvailableAddressAccountCallsCount = 0
|
||||
var getNextAvailableAddressAccountCalled: Bool {
|
||||
return getNextAvailableAddressAccountCallsCount > 0
|
||||
}
|
||||
var getNextAvailableAddressAccountReceivedAccount: Int32?
|
||||
var getNextAvailableAddressAccountReturnValue: UnifiedAddress!
|
||||
func setGetNextAvailableAddressAccountReturnValue(_ param: UnifiedAddress) async {
|
||||
getNextAvailableAddressAccountReturnValue = param
|
||||
}
|
||||
var getNextAvailableAddressAccountClosure: ((Int32) async throws -> UnifiedAddress)?
|
||||
func setGetNextAvailableAddressAccountClosure(_ param: ((Int32) async throws -> UnifiedAddress)?) async {
|
||||
getNextAvailableAddressAccountClosure = param
|
||||
}
|
||||
|
||||
func getNextAvailableAddress(account: Int32) async throws -> UnifiedAddress {
|
||||
if let error = getNextAvailableAddressAccountThrowableError {
|
||||
|
@ -2485,22 +2422,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - getMemo
|
||||
|
||||
var getMemoTxIdOutputIndexThrowableError: Error?
|
||||
func setGetMemoTxIdOutputIndexThrowableError(_ param: Error?) async {
|
||||
getMemoTxIdOutputIndexThrowableError = param
|
||||
}
|
||||
var getMemoTxIdOutputIndexCallsCount = 0
|
||||
var getMemoTxIdOutputIndexCalled: Bool {
|
||||
return getMemoTxIdOutputIndexCallsCount > 0
|
||||
}
|
||||
var getMemoTxIdOutputIndexReceivedArguments: (txId: Data, outputIndex: UInt16)?
|
||||
var getMemoTxIdOutputIndexReturnValue: Memo?
|
||||
func setGetMemoTxIdOutputIndexReturnValue(_ param: Memo?) async {
|
||||
getMemoTxIdOutputIndexReturnValue = param
|
||||
}
|
||||
var getMemoTxIdOutputIndexClosure: ((Data, UInt16) async throws -> Memo?)?
|
||||
func setGetMemoTxIdOutputIndexClosure(_ param: ((Data, UInt16) async throws -> Memo?)?) async {
|
||||
getMemoTxIdOutputIndexClosure = param
|
||||
}
|
||||
|
||||
func getMemo(txId: Data, outputIndex: UInt16) async throws -> Memo? {
|
||||
if let error = getMemoTxIdOutputIndexThrowableError {
|
||||
|
@ -2518,22 +2446,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - getTransparentBalance
|
||||
|
||||
var getTransparentBalanceAccountThrowableError: Error?
|
||||
func setGetTransparentBalanceAccountThrowableError(_ param: Error?) async {
|
||||
getTransparentBalanceAccountThrowableError = param
|
||||
}
|
||||
var getTransparentBalanceAccountCallsCount = 0
|
||||
var getTransparentBalanceAccountCalled: Bool {
|
||||
return getTransparentBalanceAccountCallsCount > 0
|
||||
}
|
||||
var getTransparentBalanceAccountReceivedAccount: Int32?
|
||||
var getTransparentBalanceAccountReturnValue: Int64!
|
||||
func setGetTransparentBalanceAccountReturnValue(_ param: Int64) async {
|
||||
getTransparentBalanceAccountReturnValue = param
|
||||
}
|
||||
var getTransparentBalanceAccountClosure: ((Int32) async throws -> Int64)?
|
||||
func setGetTransparentBalanceAccountClosure(_ param: ((Int32) async throws -> Int64)?) async {
|
||||
getTransparentBalanceAccountClosure = param
|
||||
}
|
||||
|
||||
func getTransparentBalance(account: Int32) async throws -> Int64 {
|
||||
if let error = getTransparentBalanceAccountThrowableError {
|
||||
|
@ -2551,22 +2470,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - initDataDb
|
||||
|
||||
var initDataDbSeedThrowableError: Error?
|
||||
func setInitDataDbSeedThrowableError(_ param: Error?) async {
|
||||
initDataDbSeedThrowableError = param
|
||||
}
|
||||
var initDataDbSeedCallsCount = 0
|
||||
var initDataDbSeedCalled: Bool {
|
||||
return initDataDbSeedCallsCount > 0
|
||||
}
|
||||
var initDataDbSeedReceivedSeed: [UInt8]?
|
||||
var initDataDbSeedReturnValue: DbInitResult!
|
||||
func setInitDataDbSeedReturnValue(_ param: DbInitResult) async {
|
||||
initDataDbSeedReturnValue = param
|
||||
}
|
||||
var initDataDbSeedClosure: (([UInt8]?) async throws -> DbInitResult)?
|
||||
func setInitDataDbSeedClosure(_ param: (([UInt8]?) async throws -> DbInitResult)?) async {
|
||||
initDataDbSeedClosure = param
|
||||
}
|
||||
|
||||
func initDataDb(seed: [UInt8]?) async throws -> DbInitResult {
|
||||
if let error = initDataDbSeedThrowableError {
|
||||
|
@ -2584,22 +2494,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - listTransparentReceivers
|
||||
|
||||
var listTransparentReceiversAccountThrowableError: Error?
|
||||
func setListTransparentReceiversAccountThrowableError(_ param: Error?) async {
|
||||
listTransparentReceiversAccountThrowableError = param
|
||||
}
|
||||
var listTransparentReceiversAccountCallsCount = 0
|
||||
var listTransparentReceiversAccountCalled: Bool {
|
||||
return listTransparentReceiversAccountCallsCount > 0
|
||||
}
|
||||
var listTransparentReceiversAccountReceivedAccount: Int32?
|
||||
var listTransparentReceiversAccountReturnValue: [TransparentAddress]!
|
||||
func setListTransparentReceiversAccountReturnValue(_ param: [TransparentAddress]) async {
|
||||
listTransparentReceiversAccountReturnValue = param
|
||||
}
|
||||
var listTransparentReceiversAccountClosure: ((Int32) async throws -> [TransparentAddress])?
|
||||
func setListTransparentReceiversAccountClosure(_ param: ((Int32) async throws -> [TransparentAddress])?) async {
|
||||
listTransparentReceiversAccountClosure = param
|
||||
}
|
||||
|
||||
func listTransparentReceivers(account: Int32) async throws -> [TransparentAddress] {
|
||||
if let error = listTransparentReceiversAccountThrowableError {
|
||||
|
@ -2617,22 +2518,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - getVerifiedTransparentBalance
|
||||
|
||||
var getVerifiedTransparentBalanceAccountThrowableError: Error?
|
||||
func setGetVerifiedTransparentBalanceAccountThrowableError(_ param: Error?) async {
|
||||
getVerifiedTransparentBalanceAccountThrowableError = param
|
||||
}
|
||||
var getVerifiedTransparentBalanceAccountCallsCount = 0
|
||||
var getVerifiedTransparentBalanceAccountCalled: Bool {
|
||||
return getVerifiedTransparentBalanceAccountCallsCount > 0
|
||||
}
|
||||
var getVerifiedTransparentBalanceAccountReceivedAccount: Int32?
|
||||
var getVerifiedTransparentBalanceAccountReturnValue: Int64!
|
||||
func setGetVerifiedTransparentBalanceAccountReturnValue(_ param: Int64) async {
|
||||
getVerifiedTransparentBalanceAccountReturnValue = param
|
||||
}
|
||||
var getVerifiedTransparentBalanceAccountClosure: ((Int32) async throws -> Int64)?
|
||||
func setGetVerifiedTransparentBalanceAccountClosure(_ param: ((Int32) async throws -> Int64)?) async {
|
||||
getVerifiedTransparentBalanceAccountClosure = param
|
||||
}
|
||||
|
||||
func getVerifiedTransparentBalance(account: Int32) async throws -> Int64 {
|
||||
if let error = getVerifiedTransparentBalanceAccountThrowableError {
|
||||
|
@ -2650,18 +2542,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - rewindToHeight
|
||||
|
||||
var rewindToHeightHeightThrowableError: Error?
|
||||
func setRewindToHeightHeightThrowableError(_ param: Error?) async {
|
||||
rewindToHeightHeightThrowableError = param
|
||||
}
|
||||
var rewindToHeightHeightCallsCount = 0
|
||||
var rewindToHeightHeightCalled: Bool {
|
||||
return rewindToHeightHeightCallsCount > 0
|
||||
}
|
||||
var rewindToHeightHeightReceivedHeight: Int32?
|
||||
var rewindToHeightHeightClosure: ((Int32) async throws -> Void)?
|
||||
func setRewindToHeightHeightClosure(_ param: ((Int32) async throws -> Void)?) async {
|
||||
rewindToHeightHeightClosure = param
|
||||
}
|
||||
|
||||
func rewindToHeight(height: Int32) async throws {
|
||||
if let error = rewindToHeightHeightThrowableError {
|
||||
|
@ -2675,18 +2561,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - rewindCacheToHeight
|
||||
|
||||
var rewindCacheToHeightHeightThrowableError: Error?
|
||||
func setRewindCacheToHeightHeightThrowableError(_ param: Error?) async {
|
||||
rewindCacheToHeightHeightThrowableError = param
|
||||
}
|
||||
var rewindCacheToHeightHeightCallsCount = 0
|
||||
var rewindCacheToHeightHeightCalled: Bool {
|
||||
return rewindCacheToHeightHeightCallsCount > 0
|
||||
}
|
||||
var rewindCacheToHeightHeightReceivedHeight: Int32?
|
||||
var rewindCacheToHeightHeightClosure: ((Int32) async throws -> Void)?
|
||||
func setRewindCacheToHeightHeightClosure(_ param: ((Int32) async throws -> Void)?) async {
|
||||
rewindCacheToHeightHeightClosure = param
|
||||
}
|
||||
|
||||
func rewindCacheToHeight(height: Int32) async throws {
|
||||
if let error = rewindCacheToHeightHeightThrowableError {
|
||||
|
@ -2700,18 +2580,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - putSaplingSubtreeRoots
|
||||
|
||||
var putSaplingSubtreeRootsStartIndexRootsThrowableError: Error?
|
||||
func setPutSaplingSubtreeRootsStartIndexRootsThrowableError(_ param: Error?) async {
|
||||
putSaplingSubtreeRootsStartIndexRootsThrowableError = param
|
||||
}
|
||||
var putSaplingSubtreeRootsStartIndexRootsCallsCount = 0
|
||||
var putSaplingSubtreeRootsStartIndexRootsCalled: Bool {
|
||||
return putSaplingSubtreeRootsStartIndexRootsCallsCount > 0
|
||||
}
|
||||
var putSaplingSubtreeRootsStartIndexRootsReceivedArguments: (startIndex: UInt64, roots: [SubtreeRoot])?
|
||||
var putSaplingSubtreeRootsStartIndexRootsClosure: ((UInt64, [SubtreeRoot]) async throws -> Void)?
|
||||
func setPutSaplingSubtreeRootsStartIndexRootsClosure(_ param: ((UInt64, [SubtreeRoot]) async throws -> Void)?) async {
|
||||
putSaplingSubtreeRootsStartIndexRootsClosure = param
|
||||
}
|
||||
|
||||
func putSaplingSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
|
||||
if let error = putSaplingSubtreeRootsStartIndexRootsThrowableError {
|
||||
|
@ -2725,18 +2599,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - putOrchardSubtreeRoots
|
||||
|
||||
var putOrchardSubtreeRootsStartIndexRootsThrowableError: Error?
|
||||
func setPutOrchardSubtreeRootsStartIndexRootsThrowableError(_ param: Error?) async {
|
||||
putOrchardSubtreeRootsStartIndexRootsThrowableError = param
|
||||
}
|
||||
var putOrchardSubtreeRootsStartIndexRootsCallsCount = 0
|
||||
var putOrchardSubtreeRootsStartIndexRootsCalled: Bool {
|
||||
return putOrchardSubtreeRootsStartIndexRootsCallsCount > 0
|
||||
}
|
||||
var putOrchardSubtreeRootsStartIndexRootsReceivedArguments: (startIndex: UInt64, roots: [SubtreeRoot])?
|
||||
var putOrchardSubtreeRootsStartIndexRootsClosure: ((UInt64, [SubtreeRoot]) async throws -> Void)?
|
||||
func setPutOrchardSubtreeRootsStartIndexRootsClosure(_ param: ((UInt64, [SubtreeRoot]) async throws -> Void)?) async {
|
||||
putOrchardSubtreeRootsStartIndexRootsClosure = param
|
||||
}
|
||||
|
||||
func putOrchardSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
|
||||
if let error = putOrchardSubtreeRootsStartIndexRootsThrowableError {
|
||||
|
@ -2750,18 +2618,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - updateChainTip
|
||||
|
||||
var updateChainTipHeightThrowableError: Error?
|
||||
func setUpdateChainTipHeightThrowableError(_ param: Error?) async {
|
||||
updateChainTipHeightThrowableError = param
|
||||
}
|
||||
var updateChainTipHeightCallsCount = 0
|
||||
var updateChainTipHeightCalled: Bool {
|
||||
return updateChainTipHeightCallsCount > 0
|
||||
}
|
||||
var updateChainTipHeightReceivedHeight: Int32?
|
||||
var updateChainTipHeightClosure: ((Int32) async throws -> Void)?
|
||||
func setUpdateChainTipHeightClosure(_ param: ((Int32) async throws -> Void)?) async {
|
||||
updateChainTipHeightClosure = param
|
||||
}
|
||||
|
||||
func updateChainTip(height: Int32) async throws {
|
||||
if let error = updateChainTipHeightThrowableError {
|
||||
|
@ -2775,21 +2637,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - fullyScannedHeight
|
||||
|
||||
var fullyScannedHeightThrowableError: Error?
|
||||
func setFullyScannedHeightThrowableError(_ param: Error?) async {
|
||||
fullyScannedHeightThrowableError = param
|
||||
}
|
||||
var fullyScannedHeightCallsCount = 0
|
||||
var fullyScannedHeightCalled: Bool {
|
||||
return fullyScannedHeightCallsCount > 0
|
||||
}
|
||||
var fullyScannedHeightReturnValue: BlockHeight?
|
||||
func setFullyScannedHeightReturnValue(_ param: BlockHeight?) async {
|
||||
fullyScannedHeightReturnValue = param
|
||||
}
|
||||
var fullyScannedHeightClosure: (() async throws -> BlockHeight?)?
|
||||
func setFullyScannedHeightClosure(_ param: (() async throws -> BlockHeight?)?) async {
|
||||
fullyScannedHeightClosure = param
|
||||
}
|
||||
|
||||
func fullyScannedHeight() async throws -> BlockHeight? {
|
||||
if let error = fullyScannedHeightThrowableError {
|
||||
|
@ -2806,21 +2659,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - maxScannedHeight
|
||||
|
||||
var maxScannedHeightThrowableError: Error?
|
||||
func setMaxScannedHeightThrowableError(_ param: Error?) async {
|
||||
maxScannedHeightThrowableError = param
|
||||
}
|
||||
var maxScannedHeightCallsCount = 0
|
||||
var maxScannedHeightCalled: Bool {
|
||||
return maxScannedHeightCallsCount > 0
|
||||
}
|
||||
var maxScannedHeightReturnValue: BlockHeight?
|
||||
func setMaxScannedHeightReturnValue(_ param: BlockHeight?) async {
|
||||
maxScannedHeightReturnValue = param
|
||||
}
|
||||
var maxScannedHeightClosure: (() async throws -> BlockHeight?)?
|
||||
func setMaxScannedHeightClosure(_ param: (() async throws -> BlockHeight?)?) async {
|
||||
maxScannedHeightClosure = param
|
||||
}
|
||||
|
||||
func maxScannedHeight() async throws -> BlockHeight? {
|
||||
if let error = maxScannedHeightThrowableError {
|
||||
|
@ -2837,21 +2681,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - getWalletSummary
|
||||
|
||||
var getWalletSummaryThrowableError: Error?
|
||||
func setGetWalletSummaryThrowableError(_ param: Error?) async {
|
||||
getWalletSummaryThrowableError = param
|
||||
}
|
||||
var getWalletSummaryCallsCount = 0
|
||||
var getWalletSummaryCalled: Bool {
|
||||
return getWalletSummaryCallsCount > 0
|
||||
}
|
||||
var getWalletSummaryReturnValue: WalletSummary?
|
||||
func setGetWalletSummaryReturnValue(_ param: WalletSummary?) async {
|
||||
getWalletSummaryReturnValue = param
|
||||
}
|
||||
var getWalletSummaryClosure: (() async throws -> WalletSummary?)?
|
||||
func setGetWalletSummaryClosure(_ param: (() async throws -> WalletSummary?)?) async {
|
||||
getWalletSummaryClosure = param
|
||||
}
|
||||
|
||||
func getWalletSummary() async throws -> WalletSummary? {
|
||||
if let error = getWalletSummaryThrowableError {
|
||||
|
@ -2868,21 +2703,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - suggestScanRanges
|
||||
|
||||
var suggestScanRangesThrowableError: Error?
|
||||
func setSuggestScanRangesThrowableError(_ param: Error?) async {
|
||||
suggestScanRangesThrowableError = param
|
||||
}
|
||||
var suggestScanRangesCallsCount = 0
|
||||
var suggestScanRangesCalled: Bool {
|
||||
return suggestScanRangesCallsCount > 0
|
||||
}
|
||||
var suggestScanRangesReturnValue: [ScanRange]!
|
||||
func setSuggestScanRangesReturnValue(_ param: [ScanRange]) async {
|
||||
suggestScanRangesReturnValue = param
|
||||
}
|
||||
var suggestScanRangesClosure: (() async throws -> [ScanRange])?
|
||||
func setSuggestScanRangesClosure(_ param: (() async throws -> [ScanRange])?) async {
|
||||
suggestScanRangesClosure = param
|
||||
}
|
||||
|
||||
func suggestScanRanges() async throws -> [ScanRange] {
|
||||
if let error = suggestScanRangesThrowableError {
|
||||
|
@ -2899,22 +2725,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - scanBlocks
|
||||
|
||||
var scanBlocksFromHeightFromStateLimitThrowableError: Error?
|
||||
func setScanBlocksFromHeightFromStateLimitThrowableError(_ param: Error?) async {
|
||||
scanBlocksFromHeightFromStateLimitThrowableError = param
|
||||
}
|
||||
var scanBlocksFromHeightFromStateLimitCallsCount = 0
|
||||
var scanBlocksFromHeightFromStateLimitCalled: Bool {
|
||||
return scanBlocksFromHeightFromStateLimitCallsCount > 0
|
||||
}
|
||||
var scanBlocksFromHeightFromStateLimitReceivedArguments: (fromHeight: Int32, fromState: TreeState, limit: UInt32)?
|
||||
var scanBlocksFromHeightFromStateLimitReturnValue: ScanSummary!
|
||||
func setScanBlocksFromHeightFromStateLimitReturnValue(_ param: ScanSummary) async {
|
||||
scanBlocksFromHeightFromStateLimitReturnValue = 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, fromState: TreeState, limit: UInt32) async throws -> ScanSummary {
|
||||
if let error = scanBlocksFromHeightFromStateLimitThrowableError {
|
||||
|
@ -2932,18 +2749,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - putUnspentTransparentOutput
|
||||
|
||||
var putUnspentTransparentOutputTxidIndexScriptValueHeightThrowableError: Error?
|
||||
func setPutUnspentTransparentOutputTxidIndexScriptValueHeightThrowableError(_ param: Error?) async {
|
||||
putUnspentTransparentOutputTxidIndexScriptValueHeightThrowableError = param
|
||||
}
|
||||
var putUnspentTransparentOutputTxidIndexScriptValueHeightCallsCount = 0
|
||||
var putUnspentTransparentOutputTxidIndexScriptValueHeightCalled: Bool {
|
||||
return putUnspentTransparentOutputTxidIndexScriptValueHeightCallsCount > 0
|
||||
}
|
||||
var putUnspentTransparentOutputTxidIndexScriptValueHeightReceivedArguments: (txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight)?
|
||||
var putUnspentTransparentOutputTxidIndexScriptValueHeightClosure: (([UInt8], Int, [UInt8], Int64, BlockHeight) async throws -> Void)?
|
||||
func setPutUnspentTransparentOutputTxidIndexScriptValueHeightClosure(_ param: (([UInt8], Int, [UInt8], Int64, BlockHeight) async throws -> Void)?) async {
|
||||
putUnspentTransparentOutputTxidIndexScriptValueHeightClosure = param
|
||||
}
|
||||
|
||||
func putUnspentTransparentOutput(txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight) async throws {
|
||||
if let error = putUnspentTransparentOutputTxidIndexScriptValueHeightThrowableError {
|
||||
|
@ -2957,22 +2768,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - proposeTransfer
|
||||
|
||||
var proposeTransferAccountToValueMemoThrowableError: Error?
|
||||
func setProposeTransferAccountToValueMemoThrowableError(_ param: Error?) async {
|
||||
proposeTransferAccountToValueMemoThrowableError = param
|
||||
}
|
||||
var proposeTransferAccountToValueMemoCallsCount = 0
|
||||
var proposeTransferAccountToValueMemoCalled: Bool {
|
||||
return proposeTransferAccountToValueMemoCallsCount > 0
|
||||
}
|
||||
var proposeTransferAccountToValueMemoReceivedArguments: (account: Int32, address: String, value: Int64, memo: MemoBytes?)?
|
||||
var proposeTransferAccountToValueMemoReturnValue: FfiProposal!
|
||||
func setProposeTransferAccountToValueMemoReturnValue(_ param: FfiProposal) async {
|
||||
proposeTransferAccountToValueMemoReturnValue = param
|
||||
}
|
||||
var proposeTransferAccountToValueMemoClosure: ((Int32, String, Int64, MemoBytes?) async throws -> FfiProposal)?
|
||||
func setProposeTransferAccountToValueMemoClosure(_ param: ((Int32, String, Int64, MemoBytes?) async throws -> FfiProposal)?) async {
|
||||
proposeTransferAccountToValueMemoClosure = param
|
||||
}
|
||||
|
||||
func proposeTransfer(account: Int32, to address: String, value: Int64, memo: MemoBytes?) async throws -> FfiProposal {
|
||||
if let error = proposeTransferAccountToValueMemoThrowableError {
|
||||
|
@ -2990,22 +2792,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - proposeTransferFromURI
|
||||
|
||||
var proposeTransferFromURIAccountThrowableError: Error?
|
||||
func setProposeTransferFromURIAccountThrowableError(_ param: Error?) async {
|
||||
proposeTransferFromURIAccountThrowableError = param
|
||||
}
|
||||
var proposeTransferFromURIAccountCallsCount = 0
|
||||
var proposeTransferFromURIAccountCalled: Bool {
|
||||
return proposeTransferFromURIAccountCallsCount > 0
|
||||
}
|
||||
var proposeTransferFromURIAccountReceivedArguments: (uri: String, account: Int32)?
|
||||
var proposeTransferFromURIAccountReturnValue: FfiProposal!
|
||||
func setProposeTransferFromURIAccountReturnValue(_ param: FfiProposal) async {
|
||||
proposeTransferFromURIAccountReturnValue = param
|
||||
}
|
||||
var proposeTransferFromURIAccountClosure: ((String, Int32) async throws -> FfiProposal)?
|
||||
func setProposeTransferFromURIAccountClosure(_ param: ((String, Int32) async throws -> FfiProposal)?) async {
|
||||
proposeTransferFromURIAccountClosure = param
|
||||
}
|
||||
|
||||
func proposeTransferFromURI(_ uri: String, account: Int32) async throws -> FfiProposal {
|
||||
if let error = proposeTransferFromURIAccountThrowableError {
|
||||
|
@ -3023,22 +2816,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - proposeShielding
|
||||
|
||||
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError: Error?
|
||||
func setProposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError(_ param: Error?) async {
|
||||
proposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError = param
|
||||
}
|
||||
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverCallsCount = 0
|
||||
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverCalled: Bool {
|
||||
return proposeShieldingAccountMemoShieldingThresholdTransparentReceiverCallsCount > 0
|
||||
}
|
||||
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverReceivedArguments: (account: Int32, memo: MemoBytes?, shieldingThreshold: Zatoshi, transparentReceiver: String?)?
|
||||
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverReturnValue: FfiProposal?
|
||||
func setProposeShieldingAccountMemoShieldingThresholdTransparentReceiverReturnValue(_ param: FfiProposal?) async {
|
||||
proposeShieldingAccountMemoShieldingThresholdTransparentReceiverReturnValue = param
|
||||
}
|
||||
var proposeShieldingAccountMemoShieldingThresholdTransparentReceiverClosure: ((Int32, MemoBytes?, Zatoshi, String?) async throws -> FfiProposal?)?
|
||||
func setProposeShieldingAccountMemoShieldingThresholdTransparentReceiverClosure(_ param: ((Int32, MemoBytes?, Zatoshi, String?) async throws -> FfiProposal?)?) async {
|
||||
proposeShieldingAccountMemoShieldingThresholdTransparentReceiverClosure = param
|
||||
}
|
||||
|
||||
func proposeShielding(account: Int32, memo: MemoBytes?, shieldingThreshold: Zatoshi, transparentReceiver: String?) async throws -> FfiProposal? {
|
||||
if let error = proposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError {
|
||||
|
@ -3056,22 +2840,13 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - createProposedTransactions
|
||||
|
||||
var createProposedTransactionsProposalUskThrowableError: Error?
|
||||
func setCreateProposedTransactionsProposalUskThrowableError(_ param: Error?) async {
|
||||
createProposedTransactionsProposalUskThrowableError = param
|
||||
}
|
||||
var createProposedTransactionsProposalUskCallsCount = 0
|
||||
var createProposedTransactionsProposalUskCalled: Bool {
|
||||
return createProposedTransactionsProposalUskCallsCount > 0
|
||||
}
|
||||
var createProposedTransactionsProposalUskReceivedArguments: (proposal: FfiProposal, usk: UnifiedSpendingKey)?
|
||||
var createProposedTransactionsProposalUskReturnValue: [Data]!
|
||||
func setCreateProposedTransactionsProposalUskReturnValue(_ param: [Data]) async {
|
||||
createProposedTransactionsProposalUskReturnValue = param
|
||||
}
|
||||
var createProposedTransactionsProposalUskClosure: ((FfiProposal, UnifiedSpendingKey) async throws -> [Data])?
|
||||
func setCreateProposedTransactionsProposalUskClosure(_ param: ((FfiProposal, UnifiedSpendingKey) async throws -> [Data])?) async {
|
||||
createProposedTransactionsProposalUskClosure = param
|
||||
}
|
||||
|
||||
func createProposedTransactions(proposal: FfiProposal, usk: UnifiedSpendingKey) async throws -> [Data] {
|
||||
if let error = createProposedTransactionsProposalUskThrowableError {
|
||||
|
@ -3088,25 +2863,36 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
|
||||
// MARK: - consensusBranchIdFor
|
||||
|
||||
var consensusBranchIdForHeightThrowableError: Error?
|
||||
var consensusBranchIdForHeightCallsCount = 0
|
||||
var consensusBranchIdForHeightCalled: Bool {
|
||||
return consensusBranchIdForHeightCallsCount > 0
|
||||
}
|
||||
var consensusBranchIdForHeightReceivedHeight: Int32?
|
||||
var consensusBranchIdForHeightReturnValue: Int32!
|
||||
var consensusBranchIdForHeightClosure: ((Int32) throws -> Int32)?
|
||||
|
||||
nonisolated func consensusBranchIdFor(height: Int32) throws -> Int32 {
|
||||
try consensusBranchIdForHeightClosure!(height)
|
||||
func consensusBranchIdFor(height: Int32) throws -> Int32 {
|
||||
if let error = consensusBranchIdForHeightThrowableError {
|
||||
throw error
|
||||
}
|
||||
consensusBranchIdForHeightCallsCount += 1
|
||||
consensusBranchIdForHeightReceivedHeight = height
|
||||
if let closure = consensusBranchIdForHeightClosure {
|
||||
return try closure(height)
|
||||
} else {
|
||||
return consensusBranchIdForHeightReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - initBlockMetadataDb
|
||||
|
||||
var initBlockMetadataDbThrowableError: Error?
|
||||
func setInitBlockMetadataDbThrowableError(_ param: Error?) async {
|
||||
initBlockMetadataDbThrowableError = param
|
||||
}
|
||||
var initBlockMetadataDbCallsCount = 0
|
||||
var initBlockMetadataDbCalled: Bool {
|
||||
return initBlockMetadataDbCallsCount > 0
|
||||
}
|
||||
var initBlockMetadataDbClosure: (() async throws -> Void)?
|
||||
func setInitBlockMetadataDbClosure(_ param: (() async throws -> Void)?) async {
|
||||
initBlockMetadataDbClosure = param
|
||||
}
|
||||
|
||||
func initBlockMetadataDb() async throws {
|
||||
if let error = initBlockMetadataDbThrowableError {
|
||||
|
@ -3119,18 +2905,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - writeBlocksMetadata
|
||||
|
||||
var writeBlocksMetadataBlocksThrowableError: Error?
|
||||
func setWriteBlocksMetadataBlocksThrowableError(_ param: Error?) async {
|
||||
writeBlocksMetadataBlocksThrowableError = param
|
||||
}
|
||||
var writeBlocksMetadataBlocksCallsCount = 0
|
||||
var writeBlocksMetadataBlocksCalled: Bool {
|
||||
return writeBlocksMetadataBlocksCallsCount > 0
|
||||
}
|
||||
var writeBlocksMetadataBlocksReceivedBlocks: [ZcashCompactBlock]?
|
||||
var writeBlocksMetadataBlocksClosure: (([ZcashCompactBlock]) async throws -> Void)?
|
||||
func setWriteBlocksMetadataBlocksClosure(_ param: (([ZcashCompactBlock]) async throws -> Void)?) async {
|
||||
writeBlocksMetadataBlocksClosure = param
|
||||
}
|
||||
|
||||
func writeBlocksMetadata(blocks: [ZcashCompactBlock]) async throws {
|
||||
if let error = writeBlocksMetadataBlocksThrowableError {
|
||||
|
@ -3144,21 +2924,12 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding {
|
|||
// MARK: - latestCachedBlockHeight
|
||||
|
||||
var latestCachedBlockHeightThrowableError: Error?
|
||||
func setLatestCachedBlockHeightThrowableError(_ param: Error?) async {
|
||||
latestCachedBlockHeightThrowableError = param
|
||||
}
|
||||
var latestCachedBlockHeightCallsCount = 0
|
||||
var latestCachedBlockHeightCalled: Bool {
|
||||
return latestCachedBlockHeightCallsCount > 0
|
||||
}
|
||||
var latestCachedBlockHeightReturnValue: BlockHeight!
|
||||
func setLatestCachedBlockHeightReturnValue(_ param: BlockHeight) async {
|
||||
latestCachedBlockHeightReturnValue = param
|
||||
}
|
||||
var latestCachedBlockHeightClosure: (() async throws -> BlockHeight)?
|
||||
func setLatestCachedBlockHeightClosure(_ param: (() async throws -> BlockHeight)?) async {
|
||||
latestCachedBlockHeightClosure = param
|
||||
}
|
||||
|
||||
func latestCachedBlockHeight() async throws -> BlockHeight {
|
||||
if let error = latestCachedBlockHeightThrowableError {
|
||||
|
|
|
@ -58,51 +58,51 @@ class RustBackendMockHelper {
|
|||
rustBackend: ZcashRustBackendWelding,
|
||||
consensusBranchID: Int32? = nil
|
||||
) async {
|
||||
self.rustBackendMock = ZcashRustBackendWeldingMock(
|
||||
consensusBranchIdForHeightClosure: { height in
|
||||
if let consensusBranchID {
|
||||
return consensusBranchID
|
||||
} else {
|
||||
return try rustBackend.consensusBranchIdFor(height: height)
|
||||
}
|
||||
self.rustBackendMock = ZcashRustBackendWeldingMock()
|
||||
self.rustBackendMock.consensusBranchIdForHeightClosure = { height in
|
||||
if let consensusBranchID {
|
||||
return consensusBranchID
|
||||
} else {
|
||||
return try rustBackend.consensusBranchIdFor(height: height)
|
||||
}
|
||||
)
|
||||
await setupDefaultMock(rustBackend: rustBackend)
|
||||
}
|
||||
|
||||
private func setupDefaultMock(rustBackend: ZcashRustBackendWelding) async {
|
||||
await rustBackendMock.setLatestCachedBlockHeightReturnValue(.empty())
|
||||
await rustBackendMock.setInitBlockMetadataDbClosure() { }
|
||||
await rustBackendMock.setWriteBlocksMetadataBlocksClosure() { _ in }
|
||||
await rustBackendMock.setGetTransparentBalanceAccountReturnValue(0)
|
||||
await rustBackendMock.setListTransparentReceiversAccountReturnValue([])
|
||||
await rustBackendMock.setGetCurrentAddressAccountThrowableError(ZcashError.rustGetCurrentAddress("mocked error"))
|
||||
await rustBackendMock.setGetNextAvailableAddressAccountThrowableError(ZcashError.rustGetNextAvailableAddress("mocked error"))
|
||||
await rustBackendMock.setCreateAccountSeedTreeStateRecoverUntilThrowableError(ZcashError.rustInitAccountsTableViewingKeyCotainsNullBytes)
|
||||
await rustBackendMock.setGetMemoTxIdOutputIndexReturnValue(nil)
|
||||
await rustBackendMock.setInitDataDbSeedReturnValue(.seedRequired)
|
||||
await rustBackendMock.setGetNearestRewindHeightHeightReturnValue(-1)
|
||||
await rustBackendMock.setPutUnspentTransparentOutputTxidIndexScriptValueHeightClosure() { _, _, _, _, _ in }
|
||||
await rustBackendMock.setProposeTransferAccountToValueMemoThrowableError(ZcashError.rustCreateToAddress("mocked error"))
|
||||
await rustBackendMock.setProposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError(ZcashError.rustShieldFunds("mocked error"))
|
||||
await rustBackendMock.setCreateProposedTransactionsProposalUskThrowableError(ZcashError.rustCreateToAddress("mocked error"))
|
||||
await rustBackendMock.setDecryptAndStoreTransactionTxBytesMinedHeightThrowableError(ZcashError.rustDecryptAndStoreTransaction("mock fail"))
|
||||
|
||||
await rustBackendMock.setInitDataDbSeedClosure() { seed in
|
||||
return try await rustBackend.initDataDb(seed: seed)
|
||||
}
|
||||
|
||||
await rustBackendMock.setRewindToHeightHeightClosure() { height in
|
||||
setupDefaultMock(rustBackend: rustBackend)
|
||||
}
|
||||
|
||||
private func setupDefaultMock(rustBackend: ZcashRustBackendWelding) {
|
||||
rustBackendMock.latestCachedBlockHeightReturnValue = .empty()
|
||||
rustBackendMock.initBlockMetadataDbClosure = { }
|
||||
rustBackendMock.writeBlocksMetadataBlocksClosure = { _ in }
|
||||
rustBackendMock.getTransparentBalanceAccountReturnValue = 0
|
||||
rustBackendMock.listTransparentReceiversAccountReturnValue = []
|
||||
rustBackendMock.getCurrentAddressAccountThrowableError = ZcashError.rustGetCurrentAddress("mocked error")
|
||||
rustBackendMock.getNextAvailableAddressAccountThrowableError = ZcashError.rustGetNextAvailableAddress("mocked error")
|
||||
rustBackendMock.createAccountSeedTreeStateRecoverUntilThrowableError = ZcashError.rustInitAccountsTableViewingKeyCotainsNullBytes
|
||||
rustBackendMock.getMemoTxIdOutputIndexReturnValue = nil
|
||||
rustBackendMock.initDataDbSeedReturnValue = .seedRequired
|
||||
rustBackendMock.getNearestRewindHeightHeightReturnValue = -1
|
||||
rustBackendMock.putUnspentTransparentOutputTxidIndexScriptValueHeightClosure = { _, _, _, _, _ in }
|
||||
rustBackendMock.proposeTransferAccountToValueMemoThrowableError = ZcashError.rustCreateToAddress("mocked error")
|
||||
rustBackendMock.proposeShieldingAccountMemoShieldingThresholdTransparentReceiverThrowableError = ZcashError.rustShieldFunds("mocked error")
|
||||
rustBackendMock.createProposedTransactionsProposalUskThrowableError = ZcashError.rustCreateToAddress("mocked error")
|
||||
rustBackendMock.decryptAndStoreTransactionTxBytesMinedHeightThrowableError = ZcashError.rustDecryptAndStoreTransaction("mock fail")
|
||||
|
||||
rustBackendMock.initDataDbSeedClosure = { seed in
|
||||
try await rustBackend.initDataDb(seed: seed)
|
||||
}
|
||||
|
||||
rustBackendMock.rewindToHeightHeightClosure = { height in
|
||||
try await rustBackend.rewindToHeight(height: height)
|
||||
}
|
||||
|
||||
await rustBackendMock.setRewindCacheToHeightHeightClosure() { _ in }
|
||||
rustBackendMock.rewindCacheToHeightHeightClosure = { _ in }
|
||||
|
||||
await rustBackendMock.setSuggestScanRangesClosure() {
|
||||
rustBackendMock.suggestScanRangesClosure = {
|
||||
try await rustBackend.suggestScanRanges()
|
||||
}
|
||||
|
||||
await rustBackendMock.setScanBlocksFromHeightFromStateLimitClosure { fromHeight, fromState, limit in
|
||||
rustBackendMock.scanBlocksFromHeightFromStateLimitClosure = { fromHeight, fromState, limit in
|
||||
try await rustBackend.scanBlocks(fromHeight: fromHeight, fromState: fromState, limit: limit)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ enum TestDbBuilder {
|
|||
}
|
||||
|
||||
static func prepopulatedDataDbProvider(rustBackend: ZcashRustBackend) async throws -> ConnectionProvider? {
|
||||
let provider = SimpleConnectionProvider(path: (await rustBackend.dbData).0, readonly: true)
|
||||
let provider = SimpleConnectionProvider(path: (rustBackend.dbData).0, readonly: true)
|
||||
|
||||
let initResult = try await rustBackend.initDataDb(seed: Environment.seedBytes)
|
||||
|
||||
|
|
Loading…
Reference in New Issue