Skip to content

Commit

Permalink
Review comments addressed
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasKorba committed Jan 7, 2025
1 parent ce667eb commit a8b1524
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 29 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ and this library adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `SDKSynchronizer.getAccountBalance -> AccountBalance?` into `SDKSynchronizer.getAccountsBalances -> [AccountUUID: AccountBalance]`

## Removed
- `SDKSynchronizer.sendToAddress`, deperacted in 2.1
- `SDKSynchronizer.shieldFunds`, deperacted in 2.1
- `SDKSynchronizer.sendToAddress`, deprecated in 2.1
- `SDKSynchronizer.shieldFunds`, deprecated in 2.1

## Checkpoints

Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.24.2"),
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3"),
.package(url: "https://github.com/Electric-Coin-Company/zcash-light-client-ffi", from: "0.12.0")
.package(url: "https://github.com/Electric-Coin-Company/zcash-light-client-ffi", exact: "0.12.0")
],
targets: [
.target(
Expand Down
2 changes: 1 addition & 1 deletion Sources/ZcashLightClientKit/Constants/ZcashSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public enum ZcashSDKTestnetConstants: NetworkConstants {
public static let defaultDbNamePrefix = "ZcashSdk_testnet_"
}

/// Used when importing an aaccount `importAccount(..., purpose: AccountPurpose)`
/// Used when importing an account `importAccount(..., purpose: AccountPurpose)`
public enum AccountPurpose: UInt32, Equatable {
case spending = 0
case viewOnly
Expand Down
12 changes: 12 additions & 0 deletions Sources/ZcashLightClientKit/Error/ZcashError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,14 @@ public enum ZcashError: Equatable, Error {
/// - `rustError` contains error generated by the rust layer.
/// ZRUST0071
case rustExtractAndStoreTxFromPCZT(_ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.getAccount
/// - `rustError` contains error generated by the rust layer.
/// ZRUST0072
case rustUUIDAccountNotFound(_ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.extractAndStoreTxFromPCZT
/// - `rustError` contains error generated by the rust layer.
/// ZRUST0073
case rustTxidPtrIncorrectLength(_ rustError: String)
/// SQLite query failed when fetching all accounts from the database.
/// - `sqliteError` is error produced by SQLite library.
/// ZADAO0001
Expand Down Expand Up @@ -757,6 +765,8 @@ public enum ZcashError: Equatable, Error {
case .rustCreatePCZTFromProposal: return "Error from rust layer when calling ZcashRustBackend.createPCZTFromProposal"
case .rustAddProofsToPCZT: return "Error from rust layer when calling ZcashRustBackend.addProofsToPCZT"
case .rustExtractAndStoreTxFromPCZT: return "Error from rust layer when calling ZcashRustBackend.extractAndStoreTxFromPCZT"
case .rustUUIDAccountNotFound: return "Error from rust layer when calling ZcashRustBackend.getAccount"
case .rustTxidPtrIncorrectLength: return "Error from rust layer when calling ZcashRustBackend.extractAndStoreTxFromPCZT"
case .accountDAOGetAll: return "SQLite query failed when fetching all accounts from the database."
case .accountDAOGetAllCantDecode: return "Fetched accounts from SQLite but can't decode them."
case .accountDAOFindBy: return "SQLite query failed when seaching for accounts in the database."
Expand Down Expand Up @@ -947,6 +957,8 @@ public enum ZcashError: Equatable, Error {
case .rustCreatePCZTFromProposal: return .rustCreatePCZTFromProposal
case .rustAddProofsToPCZT: return .rustAddProofsToPCZT
case .rustExtractAndStoreTxFromPCZT: return .rustExtractAndStoreTxFromPCZT
case .rustUUIDAccountNotFound: return .rustUUIDAccountNotFound
case .rustTxidPtrIncorrectLength: return .rustTxidPtrIncorrectLength
case .accountDAOGetAll: return .accountDAOGetAll
case .accountDAOGetAllCantDecode: return .accountDAOGetAllCantDecode
case .accountDAOFindBy: return .accountDAOFindBy
Expand Down
4 changes: 4 additions & 0 deletions Sources/ZcashLightClientKit/Error/ZcashErrorCode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ public enum ZcashErrorCode: String {
case rustAddProofsToPCZT = "ZRUST0070"
/// Error from rust layer when calling ZcashRustBackend.extractAndStoreTxFromPCZT
case rustExtractAndStoreTxFromPCZT = "ZRUST0071"
/// Error from rust layer when calling ZcashRustBackend.getAccount
case rustUUIDAccountNotFound = "ZRUST0072"
/// Error from rust layer when calling ZcashRustBackend.extractAndStoreTxFromPCZT
case rustTxidPtrIncorrectLength = "ZRUST0073"
/// SQLite query failed when fetching all accounts from the database.
case accountDAOGetAll = "ZADAO0001"
/// Fetched accounts from SQLite but can't decode them.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,15 @@ enum ZcashErrorDefinition {
/// - `rustError` contains error generated by the rust layer.
// sourcery: code="ZRUST0071"
case rustExtractAndStoreTxFromPCZT(_ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.getAccount
/// - `rustError` contains error generated by the rust layer.
// sourcery: code="ZRUST0072"
case rustUUIDAccountNotFound(_ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.extractAndStoreTxFromPCZT
/// - `rustError` contains error generated by the rust layer.
// sourcery: code="ZRUST0073"
case rustTxidPtrIncorrectLength(_ rustError: String)


// MARK: - Account DAO

/// SQLite query failed when fetching all accounts from the database.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ protocol ZcashKeyDerivationBackendWelding {
func isValidUnifiedFullViewingKey(_ ufvk: String) -> Bool

/// Derives and returns a UnifiedAddress from a UnifiedFullViewingKey
/// - Parameter ufvk: UTF-8 encoded String to validate
/// - Returns: true `UnifiedAddress`
/// - Parameter ufvk: UTF-8 encoded String containing a valid UFVK
/// - Returns: the corresponding default `UnifiedAddress`
func deriveUnifiedAddressFrom(ufvk: String) throws -> UnifiedAddress

/// Derives and returns a unified spending key from the given seed and ZIP 32 account index.
Expand Down
43 changes: 34 additions & 9 deletions Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,16 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
)

guard let accountPtr else {
throw ZcashError.rustImportAccountUfvk(lastErrorMessage(fallback: "`importAccount` failed with unknown error"))
throw ZcashError.rustImportAccountUfvk(lastErrorMessage(fallback: "`getAccount` failed with unknown error"))
}

defer { zcashlc_free_account(accountPtr) }

return accountPtr.pointee.unsafeToAccount()
guard let validAccount = accountPtr.pointee.unsafeToAccount() else {
throw ZcashError.rustUUIDAccountNotFound(lastErrorMessage(fallback: "`getAccount` failed with unknown error"))
}

return validAccount
}

// swiftlint:disable:next function_parameter_count
Expand Down Expand Up @@ -358,7 +362,7 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
pcztWithProofs: Pczt,
pcztWithSigs: Pczt
) async throws -> Data {
let pcztPtr: UnsafeMutablePointer<FfiBoxedSlice>? = pcztWithProofs.withUnsafeBytes { pcztWithProofsBuffer in
let txidPtr: UnsafeMutablePointer<FfiBoxedSlice>? = pcztWithProofs.withUnsafeBytes { pcztWithProofsBuffer in
guard let pcztWithProofsBufferPtr = pcztWithProofsBuffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
return nil
}
Expand All @@ -384,15 +388,19 @@ struct ZcashRustBackend: ZcashRustBackendWelding {
}
}

guard let pcztPtr else {
guard let txidPtr else {
throw ZcashError.rustExtractAndStoreTxFromPCZT(lastErrorMessage(fallback: "`extractAndStoreTxFromPCZT` failed with unknown error"))
}

defer { zcashlc_free_boxed_slice(pcztPtr) }
guard txidPtr.pointee.len == 32 else {
throw ZcashError.rustTxidPtrIncorrectLength(lastErrorMessage(fallback: "`extractAndStoreTxFromPCZT` failed with unknown error"))
}

defer { zcashlc_free_boxed_slice(txidPtr) }

return Data(
bytes: pcztPtr.pointee.ptr,
count: Int(pcztPtr.pointee.len)
bytes: txidPtr.pointee.ptr,
count: Int(txidPtr.pointee.len)
)
}

Expand Down Expand Up @@ -1163,8 +1171,25 @@ extension FfiAccount {

/// converts an [`FfiAccount`] into a [`Account`]
/// - Note: This does not check that the converted value actually holds a valid Account
func unsafeToAccount() -> Account {
.init(
func unsafeToAccount() -> Account? {
// Invalid UUID check
guard uuidArray != [UInt8](repeating: 0, count: 16) else {
return nil
}

// Invalid ZIP 32 account index
if hd_account_index == UInt32.max {
return .init(
id: AccountUUID(id: uuidArray),
name: account_name != nil ? String(cString: account_name) : nil,
keySource: key_source != nil ? String(cString: key_source) : nil,
seedFingerprint: nil,
hdAccountIndex: nil
)
}

// Valid ZIP32 account index
return .init(
id: AccountUUID(id: uuidArray),
name: account_name != nil ? String(cString: account_name) : nil,
keySource: key_source != nil ? String(cString: key_source) : nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ protocol ZcashRustBackendWelding {
/// Returns a list of the accounts in the wallet.
func listAccounts() async throws -> [Account]

/// Adds a new account to the wallet by importing the UFVK that will be used to detect incoming
/// payments.
///
/// Derivation metadata may optionally be included. To indicate that no derivation metadata is
/// available, `seedFingerprint` and `zip32AccountIndex` should be set to `nil`. Derivation
/// metadata will not be stored unless both the seed fingerprint and the HD account index are
/// provided.
///
/// - Returns: the globally unique identifier for the account.
// swiftlint:disable:next function_parameter_count
func importAccount(
ufvk: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,12 +425,12 @@ public class SDKSynchronizer: Synchronizer {
logger: logger
)

let txIds = try await initializer.rustBackend.extractAndStoreTxFromPCZT(
let txId = try await initializer.rustBackend.extractAndStoreTxFromPCZT(
pcztWithProofs: pcztWithProofs,
pcztWithSigs: pcztWithSigs
)

let transactions = try await transactionEncoder.createTransactionsFromTxIds([txIds])
let transactions = try await transactionEncoder.fetchTransactionsForTxIds([txId])

return submitTransactions(transactions)
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/ZcashLightClientKit/Tool/DerivationTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public protocol KeyValidation {

public protocol KeyDeriving {
/// Derives and returns a UnifiedAddress from a UnifiedFullViewingKey
/// - Parameter ufvk: UTF-8 encoded String to validate
/// - Returns: true `UnifiedAddress`
/// - Parameter ufvk: UTF-8 encoded String containing a valid UFVK
/// - Returns: the corresponding default `UnifiedAddress`
func deriveUnifiedAddressFrom(ufvk: String) throws -> UnifiedAddress

/// Given the seed bytes and ZIP 32 account index, return the corresponding UnifiedSpendingKey.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ protocol TransactionEncoder {
/// - Parameter transaction: a transaction overview
func submit(transaction: EncodedTransaction) async throws

func createTransactionsFromTxIds(_ txIds: [Data]) async throws -> [ZcashTransaction.Overview]
/// Tries to fetch the transaction for the given transction ids.
/// - Parameter txIds: an array of transaction ids to be fetched from the DB.
func fetchTransactionsForTxIds(_ txIds: [Data]) async throws -> [ZcashTransaction.Overview]

func closeDBConnection()
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,10 @@ class WalletTransactionEncoder: TransactionEncoder {
usk: spendingKey
)

return try await createTransactionsFromTxIds(txIds)
return try await fetchTransactionsForTxIds(txIds)
}

func createTransactionsFromTxIds(_ txIds: [Data]) async throws -> [ZcashTransaction.Overview] {
guard ensureParams(spend: self.spendParamsURL, output: self.outputParamsURL) else {
throw ZcashError.walletTransEncoderCreateTransactionMissingSaplingParams
}

func fetchTransactionsForTxIds(_ txIds: [Data]) async throws -> [ZcashTransaction.Overview] {
logger.debug("transaction ids: \(txIds)")

var txs: [ZcashTransaction.Overview] = []
Expand Down
2 changes: 1 addition & 1 deletion Tests/PerformanceTests/SynchronizerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class SynchronizerTests: ZcashTestCase {
rustBackend = nil
}

// TODO: [#1518] Fix the test, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1518
// TODO: [#1521] Fix the test, https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1521
func _testHundredBlocksSync() async throws {
guard let seedData = Data(base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg==") else {
XCTFail("seedData expected to be successfuly instantiated.")
Expand Down
3 changes: 2 additions & 1 deletion Tests/TestUtils/TestsData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,6 @@ class TestsData {
}

extension TestsData {
static let mockedAccountUUID = AccountUUID(id: Array<UInt8>(repeating: 0, count: 16))
/// `mockedAccountUUID` is used to mock the rust backend for check only purposes. It's never passed to it.
static let mockedAccountUUID = AccountUUID(id: [UInt8](repeating: 0, count: 16))
}

0 comments on commit a8b1524

Please sign in to comment.