Fix nomination pools staking data query: use parent chain for exposures

For Asset Hub nomination pools, validator exposures and prefs must be
fetched from the parent relay chain, not Asset Hub itself.
This commit is contained in:
2026-02-09 20:58:39 +03:00
parent 66879ae3c1
commit 97d2c803bf
2 changed files with 11 additions and 4 deletions
@@ -13,9 +13,11 @@ import io.novafoundation.nova.feature_account_api.data.model.AccountIdMap
import io.novafoundation.nova.feature_staking_api.domain.model.Exposure
import io.novafoundation.nova.feature_staking_impl.data.StakingOption
import io.novafoundation.nova.feature_staking_impl.data.chain
import io.novafoundation.nova.feature_staking_impl.data.stakingType
import io.novafoundation.nova.feature_staking_api.domain.nominationPool.model.PoolId
import io.novafoundation.nova.feature_staking_impl.data.unwrapNominationPools
import io.novafoundation.nova.feature_staking_impl.domain.common.StakingSharedComputation
import io.novafoundation.nova.feature_staking_impl.domain.nominationPools.stakingBackingChainId
import io.novafoundation.nova.feature_staking_impl.domain.common.electedExposuresInActiveEra
import io.novafoundation.nova.feature_staking_impl.domain.nominationPools.common.NominationPoolSharedComputation
import io.novafoundation.nova.feature_staking_impl.domain.rewards.RewardCalculator
@@ -28,6 +30,8 @@ class NominationPoolRewardCalculatorFactory(
suspend fun create(stakingOption: StakingOption, sharedComputationScope: CoroutineScope): NominationPoolRewardCalculator {
val chainId = stakingOption.chain.id
// For nomination pools on parachains (like Asset Hub), get exposures from parent relay chain
val stakingBackingChainId = stakingOption.chain.stakingBackingChainId(stakingOption.stakingType)
val delegateOption = stakingOption.unwrapNominationPools()
@@ -38,7 +42,7 @@ class NominationPoolRewardCalculatorFactory(
return RealNominationPoolRewardCalculator(
directStakingDelegate = delegate,
exposures = sharedStakingSharedComputation.electedExposuresInActiveEra(stakingOption.assetWithChain.chain.id, sharedComputationScope),
exposures = sharedStakingSharedComputation.electedExposuresInActiveEra(stakingBackingChainId, sharedComputationScope),
commissions = poolCommissions,
poolStashesById = allPoolAccounts
)
@@ -13,6 +13,7 @@ import io.novafoundation.nova.feature_staking_impl.data.repository.VaraRepositor
import io.novafoundation.nova.feature_staking_impl.data.stakingType
import io.novafoundation.nova.feature_staking_impl.data.unwrapNominationPools
import io.novafoundation.nova.feature_staking_impl.domain.common.StakingSharedComputation
import io.novafoundation.nova.feature_staking_impl.domain.nominationPools.stakingBackingChainId
import io.novafoundation.nova.feature_staking_impl.domain.common.electedExposuresInActiveEra
import io.novafoundation.nova.feature_staking_impl.domain.common.eraTimeCalculator
import io.novafoundation.nova.feature_staking_impl.domain.error.accountIdNotFound
@@ -64,10 +65,12 @@ class RewardCalculatorFactory(
}
suspend fun create(stakingOption: StakingOption, scope: CoroutineScope): RewardCalculator = withContext(Dispatchers.Default) {
val chainId = stakingOption.assetWithChain.chain.id
val chain = stakingOption.assetWithChain.chain
// For nomination pools on parachains (like Asset Hub), get exposures from parent relay chain
val stakingBackingChainId = chain.stakingBackingChainId(stakingOption.stakingType)
val exposures = shareStakingSharedComputation.get().electedExposuresInActiveEra(chainId, scope)
val validatorsPrefs = stakingRepository.getValidatorPrefs(chainId, exposures.keys)
val exposures = shareStakingSharedComputation.get().electedExposuresInActiveEra(stakingBackingChainId, scope)
val validatorsPrefs = stakingRepository.getValidatorPrefs(stakingBackingChainId, exposures.keys)
create(stakingOption, exposures, validatorsPrefs, scope)
}