diff --git a/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt b/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt index 14041e6f..08377910 100644 --- a/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt +++ b/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt @@ -29,9 +29,9 @@ import kotlin.time.Duration.Companion.seconds * Activity, so we collect it ourselves here via the same AssetsFeatureApi.updateSystem instance the real app * uses, instead of relying on app UI lifecycle to start it. * - * If this test fails, the failure message + logcat (tag "BalancesDiag", plus the standard per-updater error - * logs already wired into BalancesUpdateSystem/FullSyncPaymentUpdater) shows exactly which decision branch or - * exception is responsible - not another layer of inference from silence. + * If this test fails, the standard per-updater error logs already wired into BalancesUpdateSystem/ + * FullSyncPaymentUpdater/NativeAssetBalance show exactly which decision branch or exception is responsible - + * not another layer of inference from silence. */ class PezkuwiFullArchitectureBalancesTest { @@ -69,8 +69,8 @@ class PezkuwiFullArchitectureBalancesTest { assertNotNull( "No `assets` row was ever written for HEZ on Pezkuwi Asset Hub (metaId=$metaId) within 90s. " + - "The real BalancesUpdateSystem pipeline never completed a sync for this asset - check logcat " + - "tag 'BalancesDiag' and the standard FullSyncPaymentUpdater/StatemineAssetBalance error logs.", + "The real BalancesUpdateSystem pipeline never completed a sync for this asset - check the " + + "standard FullSyncPaymentUpdater/NativeAssetBalance error logs in logcat.", assetRow ) } finally { diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/data/network/BalancesUpdateSystem.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/data/network/BalancesUpdateSystem.kt index a6753875..820ef106 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/data/network/BalancesUpdateSystem.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/data/network/BalancesUpdateSystem.kt @@ -45,11 +45,6 @@ class BalancesUpdateSystem( } private suspend fun balancesSync(chain: Chain, metaAccount: MetaAccount): Flow { - Log.d( - "BalancesDiag", - "balancesSync(${chain.name}): hasAccountIn=${metaAccount.hasAccountIn(chain)} " + - "isDisabled=${chain.connectionState.isDisabled} canPerformFullSync=${chain.canPerformFullSync()}" - ) return when { !metaAccount.hasAccountIn(chain) -> emptyFlow() chain.connectionState.isDisabled -> emptyFlow() @@ -97,7 +92,7 @@ class BalancesUpdateSystem( // Was silently swallowed here with zero logging - listenForUpdates() itself is a suspend // call that can throw synchronously (e.g. FullSyncPaymentUpdater.listenForUpdates() calling // requireAccountIdIn(chain)), before ever returning a flow for the .catch{} above to guard. - Log.e("BalancesDiag", "listenForUpdates() threw synchronously for ${updater.javaClass.simpleName} in ${chain.name}", e) + Log.e(LOG_TAG, "listenForUpdates() threw synchronously for ${updater.javaClass.simpleName} in ${chain.name}", e) emptyFlow() } } diff --git a/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/assets/balances/utility/NativeAssetBalance.kt b/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/assets/balances/utility/NativeAssetBalance.kt index c9513444..7f9df0c1 100644 --- a/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/assets/balances/utility/NativeAssetBalance.kt +++ b/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/assets/balances/utility/NativeAssetBalance.kt @@ -1,6 +1,7 @@ package io.novafoundation.nova.feature_wallet_impl.data.network.blockchain.assets.balances.utility import android.util.Log +import io.novafoundation.nova.common.data.network.runtime.binding.AccountInfo import io.novafoundation.nova.common.data.network.runtime.binding.bindList import io.novafoundation.nova.common.data.network.runtime.binding.bindNumber import io.novafoundation.nova.common.data.network.runtime.binding.castToDictEnum @@ -17,7 +18,6 @@ import io.novafoundation.nova.core_db.dao.LockDao import io.novafoundation.nova.core_db.model.BalanceHoldLocal import io.novafoundation.nova.feature_account_api.domain.model.MetaAccount import io.novafoundation.nova.feature_wallet_api.data.cache.AssetCache -import io.novafoundation.nova.feature_wallet_api.data.cache.bindAccountInfoOrDefault import io.novafoundation.nova.feature_wallet_api.data.cache.updateAsset import io.novafoundation.nova.feature_wallet_api.data.network.blockhain.assets.balances.AssetBalance import io.novafoundation.nova.feature_wallet_api.data.network.blockhain.assets.balances.BalanceSyncUpdate @@ -154,6 +154,14 @@ class NativeAssetBalance( // Setup/subscription failures are allowed to propagate rather than being swallowed into emptyFlow()/NoCause: // the caller, FullSyncPaymentUpdater.syncAsset(), wraps this whole call in a single retryWhen boundary meant // to catch and retry exactly these failures. Swallowing here would make that retry boundary never trigger. + // + // Uses the typed remoteStorage.subscribe { metadata.system.account... } DSL (same as this class's own + // subscribeAccountBalanceUpdatePoint() and PooledBalanceUpdater/BalanceLocksUpdater) instead of a raw + // subscriptionBuilder.subscribe(key) call: on chains with several other assets/updaters already sharing + // the same SharedRequestsBuilder (e.g. Pezkuwi Asset Hub's 5 statemine assets + nomination-pools updater), + // the raw form's System.Account subscription was silently never reaching the wire - no exception, no data, + // ever - while every other asset on the same chain synced fine. The typed DSL is what every other caller + // on a busy shared connection already uses successfully. override suspend fun startSyncingBalance( chain: Chain, chainAsset: Chain.Asset, @@ -161,26 +169,18 @@ class NativeAssetBalance( accountId: AccountId, subscriptionBuilder: SharedRequestsBuilder ): Flow { - Log.d("BalancesDiag", "NativeAssetBalance.startSyncingBalance() ENTERED for ${chainAsset.symbol} on ${chain.name}") + return remoteStorage.subscribe(chain.id, subscriptionBuilder) { + metadata.system.account.observeWithRaw(accountId) + }.map { change -> + val accountInfo = change.value ?: AccountInfo.empty() + val assetChanged = assetCache.updateAsset(metaAccount.id, chain.utilityAsset, accountInfo) - val runtime = chainRegistry.getRuntime(chain.id) - Log.d("BalancesDiag", "NativeAssetBalance: got runtime for ${chain.name}") - - val key = runtime.metadata.system().storage("Account").storageKey(runtime, accountId) - Log.d("BalancesDiag", "NativeAssetBalance: computed key for ${chainAsset.symbol} on ${chain.name}: $key") - - return subscriptionBuilder.subscribe(key) - .map { change -> - Log.d("BalancesDiag", "NativeAssetBalance: received change for ${chainAsset.symbol} on ${chain.name}") - val accountInfo = bindAccountInfoOrDefault(change.value, runtime) - val assetChanged = assetCache.updateAsset(metaAccount.id, chain.utilityAsset, accountInfo) - - if (assetChanged) { - BalanceSyncUpdate.CauseFetchable(change.block) - } else { - BalanceSyncUpdate.NoCause - } + if (assetChanged) { + BalanceSyncUpdate.CauseFetchable(change.at!!) + } else { + BalanceSyncUpdate.NoCause } + } } private fun bindBalanceHolds(dynamicInstance: Any?): List? { diff --git a/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/updaters/balance/FullSyncPaymentUpdater.kt b/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/updaters/balance/FullSyncPaymentUpdater.kt index fae660a6..4b318e93 100644 --- a/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/updaters/balance/FullSyncPaymentUpdater.kt +++ b/feature-wallet-impl/src/main/java/io/novafoundation/nova/feature_wallet_impl/data/network/blockchain/updaters/balance/FullSyncPaymentUpdater.kt @@ -46,14 +46,7 @@ internal class FullSyncPaymentUpdater( ): Flow { val accountId = scopeValue.requireAccountIdIn(chain) - val enabled = chain.enabledAssets() - Log.d( - "BalancesDiag", - "FullSyncPaymentUpdater(${chain.name}): allAssets=${chain.assets.map { "${it.symbol}(id=${it.id},enabled=${it.enabled},type=${it.type})" }} " + - "enabledAssets=${enabled.map { it.symbol }}" - ) - - return enabled.map { chainAsset -> + return chain.enabledAssets().map { chainAsset -> syncAsset(chainAsset, scopeValue, accountId, storageSubscriptionBuilder) } .mergeIfMultiple()