Skip to content

Commit

Permalink
Merge pull request #1364 from LukasKorba/1363-Expose-PoolBalance-Zato…
Browse files Browse the repository at this point in the history
…shi-values

[#1363] Account balances in the SynchronizerState
  • Loading branch information
LukasKorba authored Feb 1, 2024
2 parents cc4f1ef + 9fab46a commit 170408d
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 44 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this library will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this library adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

# [Unreleased]

## Changed

### [#1363] Account balances in the SynchronizerState
`shieldedBalance: WalletBalance` has been replaced with `accountBalances: AccountBalance`. `AccountBalance` provides the same values as `shieldedBalance` but adds up a pending changes. Under the hood this calls rust's `getWalletSummary` which improved also the syncing initial values of % and balances.

# 2.0.8 - 2024-01-30

Adopt `zcash-light-client-ffi 0.5.1`. This fixes a serialization problem
Expand Down
4 changes: 2 additions & 2 deletions Sources/ZcashLightClientKit/Block/Actions/ScanAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ final class ScanAction {
let rustBackend: ZcashRustBackendWelding
let latestBlocksDataProvider: LatestBlocksDataProvider
let logger: Logger
var progressReportReducer = Constants.reportDelay
var progressReportReducer = 0

init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider
Expand Down Expand Up @@ -99,7 +99,7 @@ extension ScanAction: Action {
}

func stop() async {
progressReportReducer = Constants.reportDelay
progressReportReducer = 0
}
}

Expand Down
20 changes: 12 additions & 8 deletions Sources/ZcashLightClientKit/Model/WalletSummary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@

import Foundation

struct PoolBalance: Equatable {
let spendableValue: Zatoshi
let changePendingConfirmation: Zatoshi
let valuePendingSpendability: Zatoshi
public struct PoolBalance: Equatable {
public let spendableValue: Zatoshi
public let changePendingConfirmation: Zatoshi
public let valuePendingSpendability: Zatoshi

func total() -> Zatoshi {
static let zero = PoolBalance(spendableValue: .zero, changePendingConfirmation: .zero, valuePendingSpendability: .zero)

public func total() -> Zatoshi {
self.spendableValue + self.changePendingConfirmation + self.valuePendingSpendability
}
}

struct AccountBalance: Equatable {
let saplingBalance: PoolBalance
let unshielded: Zatoshi
public struct AccountBalance: Equatable {
public let saplingBalance: PoolBalance
public let unshielded: Zatoshi

static let zero = AccountBalance(saplingBalance: .zero, unshielded: .zero)
}

struct ScanProgress: Equatable {
Expand Down
15 changes: 10 additions & 5 deletions Sources/ZcashLightClientKit/Synchronizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public struct SynchronizerState: Equatable {
/// given how application lifecycle varies between OS Versions, platforms, etc.
/// SyncSessionIDs are provided to users
public var syncSessionID: UUID
/// shielded balance known to this synchronizer given the data that has processed locally
public var shieldedBalance: WalletBalance
/// account (shielded) balances known to this synchronizer given the data that has processed locally
public var accountBalances: AccountBalance
/// transparent balance known to this synchronizer given the data that has processed locally
public var transparentBalance: WalletBalance
/// status of the whole sync process
Expand All @@ -49,7 +49,7 @@ public struct SynchronizerState: Equatable {
public static var zero: SynchronizerState {
SynchronizerState(
syncSessionID: .nullID,
shieldedBalance: .zero,
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .unprepared,
latestBlockHeight: .zero
Expand All @@ -58,13 +58,13 @@ public struct SynchronizerState: Equatable {

init(
syncSessionID: UUID,
shieldedBalance: WalletBalance,
accountBalances: AccountBalance,
transparentBalance: WalletBalance,
internalSyncStatus: InternalSyncStatus,
latestBlockHeight: BlockHeight
) {
self.syncSessionID = syncSessionID
self.shieldedBalance = shieldedBalance
self.accountBalances = accountBalances
self.transparentBalance = transparentBalance
self.internalSyncStatus = internalSyncStatus
self.latestBlockHeight = latestBlockHeight
Expand Down Expand Up @@ -249,6 +249,11 @@ public protocol Synchronizer: AnyObject {
/// - Returns: balance in `Zatoshi`
func getShieldedVerifiedBalance(accountIndex: Int) async throws -> Zatoshi

/// get account balances from the given account index
/// - Parameter accountIndex: the index of the account
/// - Returns: balances
func getAccountBalances(accountIndex: Int) async throws -> AccountBalance?

/// Rescans the known blocks with the current keys.
///
/// `rewind(policy:)` can be called anytime. If the sync process is in progress then it is stopped first. In this case, it make some significant
Expand Down
14 changes: 8 additions & 6 deletions Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ public class SDKSynchronizer: Synchronizer {
await blockProcessor.start(retry: retry)

case .stopped, .synced, .disconnected, .error:
await updateStatus(.syncing(0))
let syncProgress = (try? await initializer.rustBackend.getWalletSummary()?.scanProgress?.progress()) ?? 0
await updateStatus(.syncing(syncProgress))
await blockProcessor.start(retry: retry)
}
}
Expand Down Expand Up @@ -413,6 +414,10 @@ public class SDKSynchronizer: Synchronizer {
return try await blockProcessor.refreshUTXOs(tAddress: address, startHeight: height)
}

public func getAccountBalances(accountIndex: Int = 0) async throws -> AccountBalance? {
try await initializer.rustBackend.getWalletSummary()?.accountBalances[UInt32(accountIndex)]
}

public func getShieldedBalance(accountIndex: Int = 0) async throws -> Zatoshi {
try await initializer.rustBackend.getWalletSummary()?.accountBalances[UInt32(accountIndex)]?
.saplingBalance.total() ?? Zatoshi.zero
Expand Down Expand Up @@ -530,12 +535,9 @@ public class SDKSynchronizer: Synchronizer {
// MARK: notify state

private func snapshotState(status: InternalSyncStatus) async -> SynchronizerState {
return await SynchronizerState(
await SynchronizerState(
syncSessionID: syncSession.value,
shieldedBalance: WalletBalance(
verified: (try? await getShieldedVerifiedBalance()) ?? .zero,
total: (try? await getShieldedBalance()) ?? .zero
),
accountBalances: (try? await getAccountBalances()) ?? .zero,
transparentBalance: (try? await blockProcessor.getTransparentBalance(accountIndex: 0)) ?? .zero,
internalSyncStatus: status,
latestBlockHeight: latestBlocksDataProvider.latestBlockHeight
Expand Down
38 changes: 19 additions & 19 deletions Tests/DarksideTests/SynchronizerDarksideTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,35 +190,35 @@ class SynchronizerDarksideTests: ZcashTestCase {
let expectedStates: [SynchronizerState] = [
SynchronizerState(
syncSessionID: .nullID,
shieldedBalance: .zero,
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .unprepared,
latestBlockHeight: 0
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: .zero,
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(0),
latestBlockHeight: 0
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(0.9),
latestBlockHeight: 663189
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(1.0),
latestBlockHeight: 663189
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .synced,
latestBlockHeight: 663189
Expand Down Expand Up @@ -267,36 +267,36 @@ class SynchronizerDarksideTests: ZcashTestCase {
let expectedStates: [SynchronizerState] = [
SynchronizerState(
syncSessionID: .nullID,
shieldedBalance: .zero,
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .unprepared,
latestBlockHeight: 0
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: .zero,
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(0),
latestBlockHeight: 0
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(0.9),
latestBlockHeight: 663189
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(1.0),
latestBlockHeight: 663189
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .synced,
latestBlockHeight: 663189
)
Expand Down Expand Up @@ -329,29 +329,29 @@ class SynchronizerDarksideTests: ZcashTestCase {
let secondBatchOfExpectedStates: [SynchronizerState] = [
SynchronizerState(
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(0),
latestBlockHeight: 663189
),
SynchronizerState(
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(0.9),
latestBlockHeight: 663200
),
SynchronizerState(
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(1.0),
latestBlockHeight: 663200
),
SynchronizerState(
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: .synced,
latestBlockHeight: 663200
)
Expand Down
2 changes: 1 addition & 1 deletion Tests/OfflineTests/SynchronizerOfflineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ class SynchronizerOfflineTests: ZcashTestCase {
func synchronizerState(for internalSyncStatus: InternalSyncStatus) -> SynchronizerState {
SynchronizerState(
syncSessionID: .nullID,
shieldedBalance: .zero,
accountBalances: .zero,
transparentBalance: .zero,
internalSyncStatus: internalSyncStatus,
latestBlockHeight: .zero
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.1.4 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
import Combine
@testable import ZcashLightClientKit
Expand Down Expand Up @@ -1671,6 +1671,30 @@ class SynchronizerMock: Synchronizer {
}
}

// MARK: - getAccountBalances

var getAccountBalancesAccountIndexThrowableError: Error?
var getAccountBalancesAccountIndexCallsCount = 0
var getAccountBalancesAccountIndexCalled: Bool {
return getAccountBalancesAccountIndexCallsCount > 0
}
var getAccountBalancesAccountIndexReceivedAccountIndex: Int?
var getAccountBalancesAccountIndexReturnValue: AccountBalance?
var getAccountBalancesAccountIndexClosure: ((Int) async throws -> AccountBalance?)?

func getAccountBalances(accountIndex: Int) async throws -> AccountBalance? {
if let error = getAccountBalancesAccountIndexThrowableError {
throw error
}
getAccountBalancesAccountIndexCallsCount += 1
getAccountBalancesAccountIndexReceivedAccountIndex = accountIndex
if let closure = getAccountBalancesAccountIndexClosure {
return try await closure(accountIndex)
} else {
return getAccountBalancesAccountIndexReturnValue
}
}

// MARK: - rewind

var rewindCallsCount = 0
Expand Down
2 changes: 1 addition & 1 deletion Tests/TestUtils/Sourcery/generateMocks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
scriptDir=${0:a:h}
cd "${scriptDir}"

sourcery_version=2.1.4
sourcery_version=2.1.7

if which sourcery >/dev/null; then
if [[ $(sourcery --version) != $sourcery_version ]]; then
Expand Down
2 changes: 1 addition & 1 deletion Tests/TestUtils/Stubs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ extension SynchronizerState {
static var mock: SynchronizerState {
SynchronizerState(
syncSessionID: .nullID,
shieldedBalance: WalletBalance(verified: Zatoshi(100), total: Zatoshi(200)),
accountBalances: .zero,
transparentBalance: WalletBalance(verified: Zatoshi(200), total: Zatoshi(300)),
internalSyncStatus: .syncing(0),
latestBlockHeight: 222222
Expand Down

0 comments on commit 170408d

Please sign in to comment.