From 5de1b50b2930f22391fdf636b87e5f588a901544 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Mon, 24 Oct 2022 09:38:47 -0300 Subject: [PATCH] make Memo and MemoBytes parameters nullable so they can be omitted when sending to transparent receivers. update libzcashlc --- Package.resolved | 2 +- Package.swift | 2 +- .../DAO/PendingTransactionDao.swift | 12 +++++++++--- Sources/ZcashLightClientKit/Model/Memo.swift | 11 +++-------- .../ZcashLightClientKit/Rust/ZcashRustBackend.swift | 11 +++++------ .../Rust/ZcashRustBackendWelding.swift | 6 +++--- Sources/ZcashLightClientKit/Synchronizer.swift | 4 ++-- .../Synchronizer/SDKSynchronizer.swift | 13 +++++++++---- .../Transaction/PersistentTransactionManager.swift | 6 +++--- .../Transaction/TransactionEncoder.swift | 4 ++-- .../Transaction/TransactionManager.swift | 2 +- .../Transaction/WalletTransactionEncoder.swift | 12 ++++++++---- 12 files changed, 47 insertions(+), 38 deletions(-) diff --git a/Package.resolved b/Package.resolved index 11a56554..00effce4 100644 --- a/Package.resolved +++ b/Package.resolved @@ -86,7 +86,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi", "state" : { - "revision" : "0059f090e655667f9ee5ed3306bd87ca78c7711a" + "revision" : "57c2de3825aab0ab8b5f4100dc0184e52ca86ba1" } } ], diff --git a/Package.swift b/Package.swift index 1f23d8f1..ae7b4599 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.8.0"), .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.13.0"), - .package(name:"libzcashlc", url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "0059f090e655667f9ee5ed3306bd87ca78c7711a") + .package(name:"libzcashlc", url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "57c2de3825aab0ab8b5f4100dc0184e52ca86ba1") ], targets: [ .target( diff --git a/Sources/ZcashLightClientKit/DAO/PendingTransactionDao.swift b/Sources/ZcashLightClientKit/DAO/PendingTransactionDao.swift index ccc42c8c..5b25284f 100644 --- a/Sources/ZcashLightClientKit/DAO/PendingTransactionDao.swift +++ b/Sources/ZcashLightClientKit/DAO/PendingTransactionDao.swift @@ -61,7 +61,7 @@ struct PendingTransaction: PendingTransactionEntity, Decodable, Encodable { raw: entity.raw, id: entity.id, value: entity.value, - memo: entity.memo == nil ? Data(MemoBytes.empty().bytes) : entity.memo, + memo: entity.memo, rawTransactionId: entity.raw, fee: entity.fee ) @@ -179,7 +179,13 @@ struct PendingTransaction: PendingTransactionEntity, Decodable, Encodable { } extension PendingTransaction { - init(value: Zatoshi, recipient: PendingTransactionRecipient, memo: MemoBytes, account index: Int) { + init(value: Zatoshi, recipient: PendingTransactionRecipient, memo: MemoBytes?, account index: Int) { + var memoData: Data? + + if let memo = memo { + memoData = Data(memo.bytes) + } + self = PendingTransaction( recipient: recipient, accountIndex: index, @@ -194,7 +200,7 @@ extension PendingTransaction { raw: nil, id: nil, value: value, - memo: Data(memo.bytes), + memo: memoData, rawTransactionId: nil, fee: nil ) diff --git a/Sources/ZcashLightClientKit/Model/Memo.swift b/Sources/ZcashLightClientKit/Model/Memo.swift index ba646562..38cec594 100644 --- a/Sources/ZcashLightClientKit/Model/Memo.swift +++ b/Sources/ZcashLightClientKit/Model/Memo.swift @@ -225,13 +225,8 @@ extension Optional where WrappedType == String { } } -extension Optional where WrappedType == Data { - func intoMemoBytes() throws -> MemoBytes { - switch self { - case .none: - return .empty() - case .some(let data): - return try .init(bytes: data.bytes) - } +extension Data { + func intoMemoBytes() throws -> MemoBytes? { + try .init(bytes: self.bytes) } } diff --git a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift index 1ada55ca..0460dad6 100644 --- a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift +++ b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift @@ -10,7 +10,6 @@ import Foundation import libzcashlc class ZcashRustBackend: ZcashRustBackendWelding { - static let minimumConfirmations: UInt32 = 10 static func createAccount(dbData: URL, seed: [UInt8], networkType: NetworkType) throws -> UnifiedSpendingKey { @@ -37,14 +36,14 @@ class ZcashRustBackend: ZcashRustBackendWelding { usk: UnifiedSpendingKey, to address: String, value: Int64, - memo: MemoBytes, + memo: MemoBytes?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType ) -> Int64 { let dbData = dbData.osStr() - return usk.bytes.withUnsafeBufferPointer{ uskPtr in + return usk.bytes.withUnsafeBufferPointer { uskPtr in zcashlc_create_to_address( dbData.0, dbData.1, @@ -52,7 +51,7 @@ class ZcashRustBackend: ZcashRustBackendWelding { UInt(usk.bytes.count), [CChar](address.utf8CString), value, - memo.bytes, + memo?.bytes, spendParamsPath, UInt(spendParamsPath.lengthOfBytes(using: .utf8)), outputParamsPath, @@ -584,7 +583,7 @@ class ZcashRustBackend: ZcashRustBackendWelding { dbCache: URL, dbData: URL, usk: UnifiedSpendingKey, - memo: MemoBytes, + memo: MemoBytes?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType @@ -597,7 +596,7 @@ class ZcashRustBackend: ZcashRustBackendWelding { dbData.1, uskBuffer.baseAddress, UInt(usk.bytes.count), - memo.bytes, + memo?.bytes, spendParamsPath, UInt(spendParamsPath.lengthOfBytes(using: .utf8)), outputParamsPath, diff --git a/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift b/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift index 644aa28d..3f43b9b2 100644 --- a/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift +++ b/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift @@ -62,7 +62,7 @@ protocol ZcashRustBackendWelding { /// - Parameter usk: `UnifiedSpendingKey` for the account that controls the funds to be spent. /// - Parameter to: recipient address /// - Parameter value: transaction amount in Zatoshi - /// - Parameter memo: the `Memo` for this transaction + /// - Parameter memo: the `MemoBytes` for this transaction. pass `nil` when sending to transparent receivers /// - Parameter spendParamsPath: path escaped String for the filesystem locations where the spend parameters are located /// - Parameter outputParamsPath: path escaped String for the filesystem locations where the output parameters are located /// - Parameter networkType: network type of this key @@ -71,7 +71,7 @@ protocol ZcashRustBackendWelding { usk: UnifiedSpendingKey, to address: String, value: Int64, - memo: MemoBytes, + memo: MemoBytes?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType @@ -451,7 +451,7 @@ protocol ZcashRustBackendWelding { dbCache: URL, dbData: URL, usk: UnifiedSpendingKey, - memo: MemoBytes, + memo: MemoBytes?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType diff --git a/Sources/ZcashLightClientKit/Synchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer.swift index c34c53a6..535fcf5f 100644 --- a/Sources/ZcashLightClientKit/Synchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer.swift @@ -109,13 +109,13 @@ public protocol Synchronizer { /// - Parameter spendingKey: the `UnifiedSpendingKey` that allows spends to occur. /// - Parameter zatoshi: the amount to send in Zatoshi. /// - Parameter toAddress: the recipient's address. - /// - Parameter memo: the memo to include as part of the transaction. + /// - Parameter memo: an `Optional`with the memo to include as part of the transaction. send `nil` when sending to transparent receivers otherwise the function will throw an error // swiftlint:disable:next function_parameter_count func sendToAddress( spendingKey: UnifiedSpendingKey, zatoshi: Zatoshi, toAddress: Recipient, - memo: Memo + memo: Memo? ) async throws -> PendingTransactionEntity /// Shields transparent funds from the given private key into the best shielded pool of the account associated to the given `UnifiedSpendingKey`. diff --git a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift index 60311785..a7f6e13e 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift @@ -461,14 +461,19 @@ public class SDKSynchronizer: Synchronizer { spendingKey: UnifiedSpendingKey, zatoshi: Zatoshi, toAddress: Recipient, - memo: Memo + memo: Memo? ) async throws -> PendingTransactionEntity { do { try await initializer.downloadParametersIfNeeded() } catch { throw SynchronizerError.parameterMissing(underlyingError: error) } - + + if case Recipient.transparent = toAddress, + memo != nil { + throw SynchronizerError.generalError(message: "Memos can't be sent to transparent addresses.") + } + return try await createToAddress( spendingKey: spendingKey, zatoshi: zatoshi, @@ -510,13 +515,13 @@ public class SDKSynchronizer: Synchronizer { spendingKey: UnifiedSpendingKey, zatoshi: Zatoshi, recipient: Recipient, - memo: Memo + memo: Memo? ) async throws -> PendingTransactionEntity { do { let spend = try transactionManager.initSpend( zatoshi: zatoshi, recipient: .address(recipient), - memo: memo.asMemoBytes(), + memo: memo?.asMemoBytes(), from: Int(spendingKey.account) ) diff --git a/Sources/ZcashLightClientKit/Transaction/PersistentTransactionManager.swift b/Sources/ZcashLightClientKit/Transaction/PersistentTransactionManager.swift index 5343e19c..13aa089a 100644 --- a/Sources/ZcashLightClientKit/Transaction/PersistentTransactionManager.swift +++ b/Sources/ZcashLightClientKit/Transaction/PersistentTransactionManager.swift @@ -42,7 +42,7 @@ class PersistentTransactionManager: OutboundTransactionManager { func initSpend( zatoshi: Zatoshi, recipient: PendingTransactionRecipient, - memo: MemoBytes, + memo: MemoBytes?, from accountIndex: Int ) throws -> PendingTransactionEntity { guard let insertedTx = try repository.find( @@ -72,7 +72,7 @@ class PersistentTransactionManager: OutboundTransactionManager { do { let encodedTransaction = try await self.encoder.createShieldingTransaction( spendingKey: spendingKey, - memoBytes: try pendingTransaction.memo.intoMemoBytes(), + memoBytes: try pendingTransaction.memo?.intoMemoBytes(), from: pendingTransaction.accountIndex ) let transaction = try self.encoder.expandEncodedTransaction(encodedTransaction) @@ -115,7 +115,7 @@ class PersistentTransactionManager: OutboundTransactionManager { spendingKey: spendingKey, zatoshi: pendingTransaction.value, to: toAddress!, - memoBytes: try pendingTransaction.memo.intoMemoBytes(), + memoBytes: try pendingTransaction.memo?.intoMemoBytes(), from: pendingTransaction.accountIndex ) let transaction = try self.encoder.expandEncodedTransaction(encodedTransaction) diff --git a/Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift b/Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift index 22435a0f..2da43426 100644 --- a/Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift +++ b/Sources/ZcashLightClientKit/Transaction/TransactionEncoder.swift @@ -34,7 +34,7 @@ protocol TransactionEncoder { spendingKey: UnifiedSpendingKey, zatoshi: Zatoshi, to address: String, - memoBytes: MemoBytes, + memoBytes: MemoBytes?, from accountIndex: Int ) async throws -> EncodedTransaction @@ -50,7 +50,7 @@ protocol TransactionEncoder { */ func createShieldingTransaction( spendingKey: UnifiedSpendingKey, - memoBytes: MemoBytes, + memoBytes: MemoBytes?, from accountIndex: Int ) async throws -> EncodedTransaction diff --git a/Sources/ZcashLightClientKit/Transaction/TransactionManager.swift b/Sources/ZcashLightClientKit/Transaction/TransactionManager.swift index 57a9395e..e401eda8 100644 --- a/Sources/ZcashLightClientKit/Transaction/TransactionManager.swift +++ b/Sources/ZcashLightClientKit/Transaction/TransactionManager.swift @@ -17,7 +17,7 @@ protocol OutboundTransactionManager { func initSpend( zatoshi: Zatoshi, recipient: PendingTransactionRecipient, - memo: MemoBytes, + memo: MemoBytes?, from accountIndex: Int ) throws -> PendingTransactionEntity diff --git a/Sources/ZcashLightClientKit/Transaction/WalletTransactionEncoder.swift b/Sources/ZcashLightClientKit/Transaction/WalletTransactionEncoder.swift index e7e56814..1e329d2f 100644 --- a/Sources/ZcashLightClientKit/Transaction/WalletTransactionEncoder.swift +++ b/Sources/ZcashLightClientKit/Transaction/WalletTransactionEncoder.swift @@ -51,7 +51,7 @@ class WalletTransactionEncoder: TransactionEncoder { spendingKey: UnifiedSpendingKey, zatoshi: Zatoshi, to address: String, - memoBytes: MemoBytes, + memoBytes: MemoBytes?, from accountIndex: Int ) async throws -> EncodedTransaction { let txId = try createSpend( @@ -80,7 +80,7 @@ class WalletTransactionEncoder: TransactionEncoder { spendingKey: UnifiedSpendingKey, zatoshi: Zatoshi, to address: String, - memoBytes: MemoBytes, + memoBytes: MemoBytes?, from accountIndex: Int ) throws -> Int { guard ensureParams(spend: self.spendParamsURL, output: self.spendParamsURL) else { @@ -107,7 +107,7 @@ class WalletTransactionEncoder: TransactionEncoder { func createShieldingTransaction( spendingKey: UnifiedSpendingKey, - memoBytes: MemoBytes, + memoBytes: MemoBytes?, from accountIndex: Int ) async throws -> EncodedTransaction { let txId = try createShieldingSpend( @@ -129,7 +129,11 @@ class WalletTransactionEncoder: TransactionEncoder { throw TransactionEncoderError.notFound(transactionId: txId) } } - func createShieldingSpend(spendingKey: UnifiedSpendingKey, memo: MemoBytes, accountIndex: Int) throws -> Int { + func createShieldingSpend( + spendingKey: UnifiedSpendingKey, + memo: MemoBytes?, + accountIndex: Int + ) throws -> Int { guard ensureParams(spend: self.spendParamsURL, output: self.spendParamsURL) else { throw TransactionEncoderError.missingParams }