Skip to content

Commit

Permalink
Merge pull request #1446 from Electric-Coin-Company/rust-logging-and-…
Browse files Browse the repository at this point in the history
…exchange-rates

Migrate to first pre-release of FFI 0.9.0
  • Loading branch information
str4d authored Aug 14, 2024
2 parents 0523fa0 + 343630e commit a3e15f0
Show file tree
Hide file tree
Showing 46 changed files with 539 additions and 66 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ and this library adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

# Unreleased

## Added
- `Synchronizer.exchangeRateUSDStream: AnyPublisher<FiatCurrencyResult?, Never>`,
which returns the currently-cached USD/ZEC exchange rate, or `nil` if it has not yet been
fetched.
- `Synchronizer.refreshExchangeRateUSD()`, which refreshes the rate returned by
`Synchronizer.exchangeRateUSDStream`. Prices are queried over Tor (to hide the wallet's
IP address).

# 2.1.12 - 2024-07-04

## Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
"state" : {
"revision" : "f16fbed56fb3ba4f2cc53ead344a2eca77fa5aae",
"version" : "0.8.1"
"revision" : "4de1b42f99aebfc5e4f0340da8a66a4f719db9a6"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
fsBlockDbRoot: try! fsBlockDbRootURLHelper(),
generalStorageURL: try! generalStorageURLHelper(),
dataDbURL: try! dataDbURLHelper(),
torDirURL: try! torDirURLHelper(),
endpoint: DemoAppConfig.endpoint,
network: kZcashNetwork,
spendParamsURL: try! spendParamsURLHelper(),
outputParamsURL: try! outputParamsURLHelper(),
saplingParamsSourceURL: SaplingParamsSourceURL.default,
enableBackendTracing: true
saplingParamsSourceURL: SaplingParamsSourceURL.default
)

self.wallet = wallet
Expand Down Expand Up @@ -199,6 +199,15 @@ func dataDbURLHelper() throws -> URL {
)
}

func torDirURLHelper() throws -> URL {
try documentsDirectoryHelper()
.appendingPathComponent(kZcashNetwork.networkType.chainName)
.appendingPathComponent(
ZcashSDK.defaultTorDirName,
isDirectory: true
)
}

func spendParamsURLHelper() throws -> URL {
try documentsDirectoryHelper().appendingPathComponent("sapling-spend.params")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,49 @@

import UIKit
import ZcashLightClientKit
import Combine

class GetBalanceViewController: UIViewController {
@IBOutlet weak var balance: UILabel!
@IBOutlet weak var verified: UILabel!

var cancellable: AnyCancellable?

var accountBalance: AccountBalance?
var rate: FiatCurrencyResult?

override func viewDidLoad() {
super.viewDidLoad()
let synchronizer = AppDelegate.shared.sharedSynchronizer
self.title = "Account 0 Balance"

Task { @MainActor in
let balanceText = (try? await synchronizer.getAccountBalance()?.saplingBalance.total().formattedString) ?? "0.0"
let verifiedText = (try? await synchronizer.getAccountBalance()?.saplingBalance.spendableValue.formattedString) ?? "0.0"
self.balance.text = "\(balanceText) ZEC"
self.verified.text = "\(verifiedText) ZEC"
Task { @MainActor [weak self] in
self?.accountBalance = try? await synchronizer.getAccountBalance()
self?.updateLabels()
}

cancellable = synchronizer.exchangeRateUSDStream.sink { [weak self] result in
self?.rate = result
self?.updateLabels()
}

synchronizer.refreshExchangeRateUSD()
}

func updateLabels() {
DispatchQueue.main.async { [weak self] in
let balanceText = (self?.accountBalance?.saplingBalance.total().formattedString) ?? "0.0"
let verifiedText = (self?.accountBalance?.saplingBalance.spendableValue.formattedString) ?? "0.0"

if let usdZecRate = self?.rate {
let usdBalance = (self?.accountBalance?.saplingBalance.total().decimalValue ?? 0).multiplying(by: usdZecRate.rate)
let usdVerified = (self?.accountBalance?.saplingBalance.spendableValue.decimalValue ?? 0).multiplying(by: usdZecRate.rate)
self?.balance.text = "\(balanceText) ZEC\n\(usdBalance) USD\n\n(\(usdZecRate.rate) USD/ZEC)"
self?.verified.text = "\(verifiedText) ZEC\n\(usdVerified) USD"
} else {
self?.balance.text = "\(balanceText) ZEC"
self?.verified.text = "\(verifiedText) ZEC"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ class SyncBlocksListViewController: UIViewController {
fsBlockDbRoot: try! fsBlockDbRootURLHelper(),
generalStorageURL: try! generalStorageURLHelper(),
dataDbURL: try! dataDbURLHelper(),
torDirURL: try! torDirURLHelper(),
endpoint: DemoAppConfig.endpoint,
network: kZcashNetwork,
spendParamsURL: try! spendParamsURLHelper(),
outputParamsURL: try! outputParamsURLHelper(),
saplingParamsSourceURL: SaplingParamsSourceURL.default,
alias: data.alias,
loggingPolicy: .default(.debug),
enableBackendTracing: true
loggingPolicy: .default(.debug)
)

return SDKSynchronizer(initializer: initializer)
Expand Down
3 changes: 1 addition & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi",
"state" : {
"revision" : "9314c83d7a09d88e1c0bd3ff3738a50833325059",
"version" : "0.8.0"
"revision" : "4de1b42f99aebfc5e4f0340da8a66a4f719db9a6"
}
}
],
Expand Down
4 changes: 3 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.19.1"),
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1"),
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", exact: "0.8.1")
// .package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", exact: "0.8.1")
// Compiled from 2516a94f8bdc540d951c38b66e9c07e2b8c29cb4
.package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "4de1b42f99aebfc5e4f0340da8a66a4f719db9a6")
],
targets: [
.target(
Expand Down
6 changes: 6 additions & 0 deletions Sources/ZcashLightClientKit/Block/CompactBlockProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ actor CompactBlockProcessor {
let saplingParamsSourceURL: SaplingParamsSourceURL
let fsBlockCacheRoot: URL
let dataDb: URL
let torDir: URL
let spendParamsURL: URL
let outputParamsURL: URL
let enhanceBatchSize: Int
Expand All @@ -79,6 +80,7 @@ actor CompactBlockProcessor {
cacheDbURL: URL? = nil,
fsBlockCacheRoot: URL,
dataDb: URL,
torDir: URL,
spendParamsURL: URL,
outputParamsURL: URL,
saplingParamsSourceURL: SaplingParamsSourceURL,
Expand All @@ -94,6 +96,7 @@ actor CompactBlockProcessor {
self.alias = alias
self.fsBlockCacheRoot = fsBlockCacheRoot
self.dataDb = dataDb
self.torDir = torDir
self.spendParamsURL = spendParamsURL
self.outputParamsURL = outputParamsURL
self.saplingParamsSourceURL = saplingParamsSourceURL
Expand All @@ -112,6 +115,7 @@ actor CompactBlockProcessor {
alias: ZcashSynchronizerAlias,
fsBlockCacheRoot: URL,
dataDb: URL,
torDir: URL,
spendParamsURL: URL,
outputParamsURL: URL,
saplingParamsSourceURL: SaplingParamsSourceURL,
Expand All @@ -126,6 +130,7 @@ actor CompactBlockProcessor {
self.alias = alias
self.fsBlockCacheRoot = fsBlockCacheRoot
self.dataDb = dataDb
self.torDir = torDir
self.spendParamsURL = spendParamsURL
self.outputParamsURL = outputParamsURL
self.saplingParamsSourceURL = saplingParamsSourceURL
Expand All @@ -151,6 +156,7 @@ actor CompactBlockProcessor {
alias: initializer.alias,
fsBlockCacheRoot: initializer.fsBlockDbRoot,
dataDb: initializer.dataDbURL,
torDir: initializer.torDirURL,
spendParamsURL: initializer.spendParamsURL,
outputParamsURL: initializer.outputParamsURL,
saplingParamsSourceURL: initializer.saplingParamsSourceURL,
Expand Down
4 changes: 3 additions & 1 deletion Sources/ZcashLightClientKit/ClosureSynchronizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ public protocol ClosureSynchronizer {
func refreshUTXOs(address: TransparentAddress, from height: BlockHeight, completion: @escaping (Result<RefreshedUTXOs, Error>) -> Void)

func getAccountBalance(accountIndex: Int, completion: @escaping (Result<AccountBalance?, Error>) -> Void)


func refreshExchangeRateUSD()

/*
It can be missleading that these two methods are returning Publisher even this protocol is closure based. Reason is that Synchronizer doesn't
provide different implementations for these two methods. So Combine it is even here.
Expand Down
2 changes: 1 addition & 1 deletion Sources/ZcashLightClientKit/CombineSynchronizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public protocol CombineSynchronizer {

func refreshUTXOs(address: TransparentAddress, from height: BlockHeight) -> SinglePublisher<RefreshedUTXOs, Error>

func getAccountBalance(accountIndex: Int) -> SinglePublisher<AccountBalance?, Error>
func refreshExchangeRateUSD()

func rewind(_ policy: RewindPolicy) -> CompletablePublisher<Error>
func wipe() -> CompletablePublisher<Error>
Expand Down
12 changes: 12 additions & 0 deletions Sources/ZcashLightClientKit/Constants/ZcashSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ public enum ZcashSDK {
/// Default Name for LibRustZcash data.db
public static let defaultDataDbName = "data.db"

/// Default Name for Tor data directory
public static let defaultTorDirName = "tor"

/// Default Name for Compact Block file system based db
public static let defaultFsCacheName = "fs_cache"

Expand Down Expand Up @@ -154,6 +157,9 @@ public protocol NetworkConstants {
/// Default Name for LibRustZcash data.db
static var defaultDataDbName: String { get }

/// Default Name for Tor data directory
static var defaultTorDirName: String { get }

static var defaultFsBlockDbRootName: String { get }

/// Default Name for Compact Block caches db
Expand Down Expand Up @@ -181,6 +187,9 @@ public enum ZcashSDKMainnetConstants: NetworkConstants {
/// Default Name for LibRustZcash data.db
public static let defaultDataDbName = "data.db"

/// Default Name for Tor data directory
public static let defaultTorDirName = "tor"

public static let defaultFsBlockDbRootName = "fs_cache"

/// Default Name for Compact Block caches db
Expand All @@ -197,6 +206,9 @@ public enum ZcashSDKTestnetConstants: NetworkConstants {
/// Default Name for LibRustZcash data.db
public static let defaultDataDbName = "data.db"

/// Default Name for Tor data directory
public static let defaultTorDirName = "tor"

/// Default Name for Compact Block caches db
public static let defaultCacheDbName = "caches.db"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
scriptDir=${0:a:h}
cd "${scriptDir}"

sourcery_version=2.1.7
sourcery_version=2.2.5

if which sourcery >/dev/null; then
if [[ $(sourcery --version) != $sourcery_version ]]; then
echo "warning: Compatible sourcer version not installed. Install sourcer $sourcery_version. Currently installed version is $(sourcer --version)"
echo "warning: Compatible sourcery version not installed. Install sourcery $sourcery_version. Currently installed version is $(sourcery --version)"
exit 1
fi

Expand Down
21 changes: 20 additions & 1 deletion Sources/ZcashLightClientKit/Error/ZcashError.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.2.5 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT

/*
Expand Down Expand Up @@ -342,6 +342,16 @@ public enum ZcashError: Equatable, Error {
/// sourcery: code="ZRUST0061"
/// ZRUST0061
case rustPutOrchardSubtreeRoots(_ rustError: String)
/// Error from rust layer when calling TorClient.init
/// - `rustError` contains error generated by the rust layer.
/// sourcery: code="ZRUST0062"
/// ZRUST0062
case rustTorClientInit(_ rustError: String)
/// Error from rust layer when calling TorClient.get
/// - `rustError` contains error generated by the rust layer.
/// sourcery: code="ZRUST0063"
/// ZRUST0063
case rustTorClientGet(_ rustError: String)
/// SQLite query failed when fetching all accounts from the database.
/// - `sqliteError` is error produced by SQLite library.
/// ZADAO0001
Expand Down Expand Up @@ -509,6 +519,9 @@ public enum ZcashError: Equatable, Error {
/// Can't create `Recipient` because input is invalid.
/// ZWLTP0007
case recipientInvalidInput
/// Can't create `TexAddress` because input is invalid.
/// ZWLTP0008
case texAddressInvalidInput
/// WalletTransactionEncoder wants to create transaction but files with sapling parameters are not present on disk.
/// ZWLTE0001
case walletTransEncoderCreateTransactionMissingSaplingParams
Expand Down Expand Up @@ -705,6 +718,8 @@ public enum ZcashError: Equatable, Error {
case .rustIsSeedRelevantToAnyDerivedAccount: return "Error from rust layer when calling ZcashRustBackend.rustIsSeedRelevantToAnyDerivedAccount"
case .rustPutOrchardSubtreeRootsAllocationProblem: return "Unable to allocate memory required to write blocks when calling ZcashRustBackend.putOrchardSubtreeRoots"
case .rustPutOrchardSubtreeRoots: return "Error from rust layer when calling ZcashRustBackend.putOrchardSubtreeRoots"
case .rustTorClientInit: return "Error from rust layer when calling TorClient.init"
case .rustTorClientGet: return "Error from rust layer when calling TorClient.get"
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 @@ -757,6 +772,7 @@ public enum ZcashError: Equatable, Error {
case .saplingAddressInvalidInput: return "Can't create `SaplingAddress` because input is invalid."
case .unifiedAddressInvalidInput: return "Can't create `UnifiedAddress` because input is invalid."
case .recipientInvalidInput: return "Can't create `Recipient` because input is invalid."
case .texAddressInvalidInput: return "Can't create `TexAddress` because input is invalid."
case .walletTransEncoderCreateTransactionMissingSaplingParams: return "WalletTransactionEncoder wants to create transaction but files with sapling parameters are not present on disk."
case .walletTransEncoderShieldFundsMissingSaplingParams: return "WalletTransactionEncoder wants to shield funds but files with sapling parameters are not present on disk."
case .zatoshiDecode: return "Initiatilzation fo `Zatoshi` from a decoder failed."
Expand Down Expand Up @@ -885,6 +901,8 @@ public enum ZcashError: Equatable, Error {
case .rustIsSeedRelevantToAnyDerivedAccount: return .rustIsSeedRelevantToAnyDerivedAccount
case .rustPutOrchardSubtreeRootsAllocationProblem: return .rustPutOrchardSubtreeRootsAllocationProblem
case .rustPutOrchardSubtreeRoots: return .rustPutOrchardSubtreeRoots
case .rustTorClientInit: return .rustTorClientInit
case .rustTorClientGet: return .rustTorClientGet
case .accountDAOGetAll: return .accountDAOGetAll
case .accountDAOGetAllCantDecode: return .accountDAOGetAllCantDecode
case .accountDAOFindBy: return .accountDAOFindBy
Expand Down Expand Up @@ -937,6 +955,7 @@ public enum ZcashError: Equatable, Error {
case .saplingAddressInvalidInput: return .saplingAddressInvalidInput
case .unifiedAddressInvalidInput: return .unifiedAddressInvalidInput
case .recipientInvalidInput: return .recipientInvalidInput
case .texAddressInvalidInput: return .texAddressInvalidInput
case .walletTransEncoderCreateTransactionMissingSaplingParams: return .walletTransEncoderCreateTransactionMissingSaplingParams
case .walletTransEncoderShieldFundsMissingSaplingParams: return .walletTransEncoderShieldFundsMissingSaplingParams
case .zatoshiDecode: return .zatoshiDecode
Expand Down
8 changes: 7 additions & 1 deletion Sources/ZcashLightClientKit/Error/ZcashErrorCode.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.2.5 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT

/*
Expand Down Expand Up @@ -185,6 +185,10 @@ public enum ZcashErrorCode: String {
case rustPutOrchardSubtreeRootsAllocationProblem = "ZRUST0060"
/// Error from rust layer when calling ZcashRustBackend.putOrchardSubtreeRoots
case rustPutOrchardSubtreeRoots = "ZRUST0061"
/// Error from rust layer when calling TorClient.init
case rustTorClientInit = "ZRUST0062"
/// Error from rust layer when calling TorClient.get
case rustTorClientGet = "ZRUST0063"
/// SQLite query failed when fetching all accounts from the database.
case accountDAOGetAll = "ZADAO0001"
/// Fetched accounts from SQLite but can't decode them.
Expand Down Expand Up @@ -289,6 +293,8 @@ public enum ZcashErrorCode: String {
case unifiedAddressInvalidInput = "ZWLTP0006"
/// Can't create `Recipient` because input is invalid.
case recipientInvalidInput = "ZWLTP0007"
/// Can't create `TexAddress` because input is invalid.
case texAddressInvalidInput = "ZWLTP0008"
/// WalletTransactionEncoder wants to create transaction but files with sapling parameters are not present on disk.
case walletTransEncoderCreateTransactionMissingSaplingParams = "ZWLTE0001"
/// WalletTransactionEncoder wants to shield funds but files with sapling parameters are not present on disk.
Expand Down
11 changes: 11 additions & 0 deletions Sources/ZcashLightClientKit/Error/ZcashErrorCodeDefinition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,14 @@ enum ZcashErrorDefinition {
/// - `rustError` contains error generated by the rust layer.
/// sourcery: code="ZRUST0061"
case rustPutOrchardSubtreeRoots(_ rustError: String)
/// Error from rust layer when calling TorClient.init
/// - `rustError` contains error generated by the rust layer.
/// sourcery: code="ZRUST0062"
case rustTorClientInit(_ rustError: String)
/// Error from rust layer when calling TorClient.get
/// - `rustError` contains error generated by the rust layer.
/// sourcery: code="ZRUST0063"
case rustTorClientGet(_ rustError: String)

// MARK: - Account DAO

Expand Down Expand Up @@ -571,6 +579,9 @@ enum ZcashErrorDefinition {
/// Can't create `Recipient` because input is invalid.
// sourcery: code="ZWLTP0007"
case recipientInvalidInput
/// Can't create `TexAddress` because input is invalid.
// sourcery: code="ZWLTP0008"
case texAddressInvalidInput

// MARK: - WalletTransactionEncoder

Expand Down
Loading

0 comments on commit a3e15f0

Please sign in to comment.