Skip to content

Commit

Permalink
[#1109] Regular balance flows emission
Browse files Browse the repository at this point in the history
  • Loading branch information
HonzaR committed Sep 5, 2023
1 parent 1e7983e commit 1e56d2e
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 30 deletions.
42 changes: 22 additions & 20 deletions sdk-lib/src/main/java/cash/z/ecc/android/sdk/SdkSynchronizer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -176,18 +176,14 @@ class SdkSynchronizer private constructor(
}
}

// pools
private val _orchardBalances = MutableStateFlow<WalletBalance?>(null)
private val _saplingBalances = MutableStateFlow<WalletBalance?>(null)
private val _transparentBalances = MutableStateFlow<WalletBalance?>(null)

private val _status = MutableStateFlow<Synchronizer.Status>(DISCONNECTED)

var coroutineScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)

override val orchardBalances = _orchardBalances.asStateFlow()
override val saplingBalances = _saplingBalances.asStateFlow()
override val transparentBalances = _transparentBalances.asStateFlow()
override val orchardBalances = processor.orchardBalances.asStateFlow()
override val saplingBalances = processor.saplingBalances.asStateFlow()
override val transparentBalances = processor.transparentBalances.asStateFlow()

override val transactions
get() = combine(processor.networkHeight, storage.allTransactions) { networkHeight, allTransactions ->
val latestBlockHeight = networkHeight ?: storage.lastScannedHeight()
Expand Down Expand Up @@ -362,36 +358,42 @@ class SdkSynchronizer private constructor(
storage.invalidate()
}

//
// Private API
//

/**
* Calculate the latest balance, based on the blocks that have been scanned and transmit this
* information into the flow of [balances].
* Calculate the latest balance based on the blocks that have been scanned and transmit this information into the
* [transparentBalances] and [saplingBalances] flow. The [orchardBalances] flow is still not filled with proper data
* because of the current limited Orchard support.
*/
suspend fun refreshAllBalances() {
refreshSaplingBalance()
refreshTransparentBalance()
processor.checkAllBalances()
// TODO [#682]: refresh orchard balance
// TODO [#682]: https://github.com/zcash/zcash-android-wallet-sdk/issues/682
Twig.warn { "Warning: Orchard balance does not yet refresh. Only some of the plumbing is in place." }
}

/**
* Calculate the latest Sapling balance based on the blocks that have been scanned and transmit this information
* into the [saplingBalances] flow.
*/
suspend fun refreshSaplingBalance() {
Twig.debug { "refreshing sapling balance" }
_saplingBalances.value = processor.getBalanceInfo(Account.DEFAULT)
processor.checkSaplingBalance()
}

/**
* Calculate the latest Transparent balance based on the blocks that have been scanned and transmit this information
* into the [saplingBalances] flow.
*/
suspend fun refreshTransparentBalance() {
Twig.debug { "refreshing transparent balance" }
_transparentBalances.value = processor.getUtxoCacheBalance(getTransparentAddress(Account.DEFAULT))
processor.checkTransparentBalance()
}

suspend fun isValidAddress(address: String): Boolean {
return !validateAddress(address).isNotValid
}

//
// Private API
//

private fun CoroutineScope.onReady() {
Twig.debug { "Starting synchronizer…" }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ class CompactBlockProcessor internal constructor(
private val _progress = MutableStateFlow(PercentDecimal.ZERO_PERCENT)
private val _processorInfo = MutableStateFlow(ProcessorInfo(null, null, null))
private val _networkHeight = MutableStateFlow<BlockHeight?>(null)

// pools
internal val saplingBalances = MutableStateFlow<WalletBalance?>(null)
internal val orchardBalances = MutableStateFlow<WalletBalance?>(null)
internal val transparentBalances = MutableStateFlow<WalletBalance?>(null)

private val processingMutex = Mutex()

/**
Expand Down Expand Up @@ -470,6 +476,7 @@ class CompactBlockProcessor internal constructor(
lastBatchOrder = min(rangeSyncProgress.overallOrder, allBatchCountLocal)

setProgress(PercentDecimal(lastBatchOrder / allBatchCountLocal.toFloat()))
checkAllBalances()

when (rangeSyncProgress.resultState) {
SyncingResult.UpdateBirthday -> {
Expand All @@ -478,7 +485,7 @@ class CompactBlockProcessor internal constructor(
SyncingResult.EnhanceSuccess -> {
Twig.info { "Triggering transaction refresh now" }
// Invalidate transaction data
refreshTransactions(transactionStorage = repository)
checkTransactions(transactionStorage = repository)
}
is SyncingResult.Failure -> {
syncingResult = rangeSyncProgress.resultState
Expand Down Expand Up @@ -552,6 +559,7 @@ class CompactBlockProcessor internal constructor(
lastBatchOrder = min(rangeSyncProgress.overallOrder, allBatchCountLocal)

setProgress(PercentDecimal(lastBatchOrder / allBatchCountLocal.toFloat()))
checkAllBalances()

when (rangeSyncProgress.resultState) {
SyncingResult.UpdateBirthday -> {
Expand All @@ -561,7 +569,7 @@ class CompactBlockProcessor internal constructor(
SyncingResult.EnhanceSuccess -> {
Twig.info { "Triggering transaction refresh now" }
// Invalidate transaction data and return the common batch syncing success result to the caller
refreshTransactions(transactionStorage = repository)
checkTransactions(transactionStorage = repository)
SyncingResult.AllSuccess
}
is SyncingResult.Failure -> {
Expand Down Expand Up @@ -609,13 +617,6 @@ class CompactBlockProcessor internal constructor(
return BlockProcessingResult.Success
}

/**
* This invalidates transaction storage to trigger data refreshing for its subscribers.
*/
private fun refreshTransactions(transactionStorage: DerivedDataRepository) {
transactionStorage.invalidate()
}

@Suppress("ReturnCount")
internal suspend fun runSbSSyncingPreparation(
backend: TypesafeBackend,
Expand Down Expand Up @@ -714,6 +715,7 @@ class CompactBlockProcessor internal constructor(
lastBatchOrder = 0
).collect { rangeSyncProgress ->
setProgress(PercentDecimal(rangeSyncProgress.overallOrder / allBatchCount.toFloat()))
checkAllBalances()

when (rangeSyncProgress.resultState) {
SyncingResult.UpdateBirthday -> {
Expand All @@ -722,7 +724,7 @@ class CompactBlockProcessor internal constructor(
SyncingResult.EnhanceSuccess -> {
Twig.info { "Triggering transaction refresh now" }
// Invalidate transaction data
refreshTransactions(transactionStorage = repository)
checkTransactions(transactionStorage = repository)
}
is SyncingResult.Failure -> {
syncingResult = rangeSyncProgress.resultState
Expand All @@ -747,6 +749,42 @@ class CompactBlockProcessor internal constructor(
return BlockProcessingResult.Success
}

/**
* This invalidates transaction storage to trigger data refreshing for its subscribers.
*/
private fun checkTransactions(transactionStorage: DerivedDataRepository) {
transactionStorage.invalidate()
}

/**
* Calculate the latest balances, based on the blocks that have been scanned and transmit this
* information into the related internal flows. Note that the Orchard balance is not supported.
*/
internal suspend fun checkAllBalances() {
checkSaplingBalance()
checkTransparentBalance()
// TODO [#682]: refresh orchard balance
// TODO [#682]: https://github.com/zcash/zcash-android-wallet-sdk/issues/682
}

/**
* Calculate the latest Sapling balance, based on the blocks that have been scanned and transmit this
* information into the internal [saplingBalances] flow.
*/
internal suspend fun checkSaplingBalance() {
Twig.debug { "Checking Sapling balance" }
saplingBalances.value = getBalanceInfo(Account.DEFAULT)
}

/**
* Calculate the latest Transparent balance, based on the blocks that have been scanned and transmit this
* information into the internal [transparentBalances] flow.
*/
internal suspend fun checkTransparentBalance() {
Twig.debug { "Checking Transparent balance" }
transparentBalances.value = getUtxoCacheBalance(getTransparentAddress(backend, Account.DEFAULT))
}

sealed class BlockProcessingResult {
object NoBlocksToProcess : BlockProcessingResult()
object Success : BlockProcessingResult()
Expand Down

0 comments on commit 1e56d2e

Please sign in to comment.