mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-04-21 23:48:00 +00:00
fix: resolve parentId for Asset Hub staking to relay chain
ValidatorProvider, DirectStakingProperties, and DirectStakingRecommendation were querying Asset Hub chainId for staking data (validators, exposures, minStake, maxNominations) but these live on the relay chain. Added chain.parentId resolution so parachain staking correctly routes to relay. Also: - Add VoterBagsList pallet support (Pezkuwi naming) - Wrap BagListRepository queries in runCatching for binding compat - Remove debug logging
This commit is contained in:
@@ -257,7 +257,7 @@ fun Module.constantOrNull(name: String) = constants[name]
|
||||
|
||||
fun RuntimeMetadata.staking() = module(Modules.STAKING)
|
||||
|
||||
fun RuntimeMetadata.voterListOrNull() = firstExistingModuleOrNull(Modules.VOTER_LIST, Modules.BAG_LIST)
|
||||
fun RuntimeMetadata.voterListOrNull() = firstExistingModuleOrNull(Modules.VOTER_LIST, Modules.BAG_LIST, Modules.VOTER_BAGS_LIST)
|
||||
fun RuntimeMetadata.voterListName(): String = requireNotNull(voterListOrNull()).name
|
||||
|
||||
fun RuntimeMetadata.system() = module(Modules.SYSTEM)
|
||||
@@ -632,6 +632,7 @@ object Modules {
|
||||
|
||||
const val VOTER_LIST = "VoterList"
|
||||
const val BAG_LIST = "BagsList"
|
||||
const val VOTER_BAGS_LIST = "VoterBagsList"
|
||||
|
||||
const val ELECTION_PROVIDER_MULTI_PHASE = "ElectionProviderMultiPhase"
|
||||
|
||||
|
||||
+2
@@ -42,6 +42,7 @@ class ProxyCallFilterFactory {
|
||||
WhiteListFilter(Modules.SLOTS),
|
||||
WhiteListFilter(Modules.AUCTIONS),
|
||||
WhiteListFilter(Modules.VOTER_LIST),
|
||||
WhiteListFilter(Modules.VOTER_BAGS_LIST),
|
||||
WhiteListFilter(Modules.NOMINATION_POOLS),
|
||||
WhiteListFilter(Modules.FAST_UNSTAKE)
|
||||
)
|
||||
@@ -62,6 +63,7 @@ class ProxyCallFilterFactory {
|
||||
WhiteListFilter(Modules.UTILITY),
|
||||
WhiteListFilter(Modules.FAST_UNSTAKE),
|
||||
WhiteListFilter(Modules.VOTER_LIST),
|
||||
WhiteListFilter(Modules.VOTER_BAGS_LIST),
|
||||
WhiteListFilter(Modules.NOMINATION_POOLS)
|
||||
)
|
||||
|
||||
|
||||
+10
-6
@@ -42,15 +42,19 @@ class LocalBagListRepository(
|
||||
) : BagListRepository {
|
||||
|
||||
override suspend fun bagThresholds(chainId: ChainId): List<BagListNode.Score>? {
|
||||
return chainRegistry.withRuntime(chainId) {
|
||||
runtime.metadata.voterListOrNull()?.constant("BagThresholds")?.getAs(collectionOf(::score))
|
||||
}
|
||||
return runCatching {
|
||||
chainRegistry.withRuntime(chainId) {
|
||||
runtime.metadata.voterListOrNull()?.constant("BagThresholds")?.getAs(collectionOf(::score))
|
||||
}
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
override suspend fun bagListSize(chainId: ChainId): BigInteger? {
|
||||
return localStorage.query(chainId) {
|
||||
runtime.metadata.voterListOrNull()?.storage("CounterForListNodes")?.query(binding = ::bindNumber)
|
||||
}
|
||||
return runCatching {
|
||||
localStorage.query(chainId) {
|
||||
runtime.metadata.voterListOrNull()?.storage("CounterForListNodes")?.query(binding = ::bindNumber)
|
||||
}
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
override suspend fun maxElectingVotes(chainId: ChainId): BigInteger? {
|
||||
|
||||
-16
@@ -51,10 +51,6 @@ class RewardCalculatorFactory(
|
||||
val stakingChainId = stakingOption.assetWithChain.chain.parentId ?: stakingOption.assetWithChain.chain.id
|
||||
val totalIssuance = totalIssuanceRepository.getTotalIssuance(stakingChainId)
|
||||
|
||||
Log.d("PEZ_STAKING", "create(4-param) exposures=${exposures.size} validatorsPrefs=${validatorsPrefs.size}")
|
||||
Log.d("PEZ_STAKING", "exposureKeys=${exposures.keys.take(3).map { it.take(16) }}")
|
||||
Log.d("PEZ_STAKING", "prefKeys=${validatorsPrefs.keys.take(3).map { it.take(16) }}")
|
||||
|
||||
val validators = exposures.keys.mapNotNull { accountIdHex ->
|
||||
val exposure = exposures[accountIdHex] ?: accountIdNotFound(accountIdHex)
|
||||
val validatorPrefs = validatorsPrefs[accountIdHex] ?: return@mapNotNull null
|
||||
@@ -66,8 +62,6 @@ class RewardCalculatorFactory(
|
||||
)
|
||||
}
|
||||
|
||||
Log.d("PEZ_STAKING", "totalIssuance=$totalIssuance validators=${validators.size} stakingChainId=${stakingChainId.take(12)}")
|
||||
|
||||
stakingOption.createRewardCalculator(validators, totalIssuance, stakingChainId, scope)
|
||||
}
|
||||
|
||||
@@ -77,21 +71,11 @@ class RewardCalculatorFactory(
|
||||
// For parachains with a parent relay chain, staking exposures live on the relay chain
|
||||
val exposureChainId = chain.parentId ?: chainId
|
||||
|
||||
Log.d(
|
||||
"PEZ_STAKING",
|
||||
"RewardCalculatorFactory.create() chainId=${chainId.take(12)}" +
|
||||
" exposureChainId=${exposureChainId.take(12)}" +
|
||||
" stakingType=${stakingOption.additional.stakingType}"
|
||||
)
|
||||
|
||||
val activeEra = stakingRepository.getActiveEraIndex(exposureChainId)
|
||||
Log.d("PEZ_STAKING", "ActiveEra: $activeEra for ${exposureChainId.take(12)}")
|
||||
|
||||
val exposures = stakingRepository.getElectedValidatorsExposure(exposureChainId, activeEra)
|
||||
Log.d("PEZ_STAKING", "Exposures: ${exposures.size}")
|
||||
|
||||
val validatorsPrefs = stakingRepository.getValidatorPrefs(exposureChainId, exposures.keys)
|
||||
Log.d("PEZ_STAKING", "ValidatorPrefs: ${validatorsPrefs.size}")
|
||||
|
||||
create(stakingOption, exposures, validatorsPrefs, scope)
|
||||
}
|
||||
|
||||
+4
-2
@@ -98,8 +98,10 @@ private class DirectStakingProperties(
|
||||
enoughAvailableToStake()
|
||||
}
|
||||
|
||||
private val stakingChainId = stakingOption.chain.parentId ?: stakingOption.chain.id
|
||||
|
||||
override suspend fun minStake(): Balance {
|
||||
return stakingSharedComputation.minStake(stakingOption.chain.id, scope)
|
||||
return stakingSharedComputation.minStake(stakingChainId, scope)
|
||||
}
|
||||
|
||||
private fun StartMultiStakingValidationSystemBuilder.noConflictingStaking() {
|
||||
@@ -125,7 +127,7 @@ private class DirectStakingProperties(
|
||||
private fun StartMultiStakingValidationSystemBuilder.maximumNominatorsReached() {
|
||||
maximumNominatorsReached(
|
||||
stakingRepository = stakingRepository,
|
||||
chainId = { stakingOption.chain.id },
|
||||
chainId = { stakingChainId },
|
||||
errorProducer = { StartMultiStakingValidationFailure.MaxNominatorsReached(stakingType) }
|
||||
)
|
||||
}
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ class DirectStakingRecommendation(
|
||||
|
||||
override suspend fun recommendedSelection(stake: Balance): StartMultiStakingSelection {
|
||||
val provider = recommendationSettingsProvider.await()
|
||||
val maximumValidatorsPerNominator = stakingConstantsRepository.maxValidatorsPerNominator(stakingOption.chain.id, stake)
|
||||
val stakingChainId = stakingOption.chain.parentId ?: stakingOption.chain.id
|
||||
val maximumValidatorsPerNominator = stakingConstantsRepository.maxValidatorsPerNominator(stakingChainId, stake)
|
||||
val recommendationSettings = provider.recommendedSettings(maximumValidatorsPerNominator)
|
||||
val recommendator = recommendator.await()
|
||||
|
||||
|
||||
+6
-4
@@ -45,20 +45,22 @@ class ValidatorProvider(
|
||||
): List<Validator> {
|
||||
val chain = stakingOption.assetWithChain.chain
|
||||
val chainId = chain.id
|
||||
// For parachains (e.g. Asset Hub), staking validators live on the parent relay chain
|
||||
val stakingChainId = chain.parentId ?: chainId
|
||||
|
||||
val novaValidatorIds = validatorsPreferencesSource.getRecommendedValidatorIds(chainId)
|
||||
val electedValidatorExposures = stakingSharedComputation.electedExposuresInActiveEra(chainId, scope)
|
||||
val electedValidatorExposures = stakingSharedComputation.electedExposuresInActiveEra(stakingChainId, scope)
|
||||
|
||||
val requestedValidatorIds = sources.allValidatorIds(chainId, electedValidatorExposures, novaValidatorIds)
|
||||
// we always need validator prefs for elected validators to construct reward calculator
|
||||
val validatorIdsToQueryPrefs = electedValidatorExposures.keys + requestedValidatorIds
|
||||
|
||||
val validatorPrefs = stakingRepository.getValidatorPrefs(chainId, validatorIdsToQueryPrefs)
|
||||
val validatorPrefs = stakingRepository.getValidatorPrefs(stakingChainId, validatorIdsToQueryPrefs)
|
||||
val identities = identityRepository.getIdentitiesFromIdsHex(chainId, requestedValidatorIds)
|
||||
val slashes = stakingRepository.getSlashes(chain.id, requestedValidatorIds)
|
||||
val slashes = stakingRepository.getSlashes(stakingChainId, requestedValidatorIds)
|
||||
|
||||
val rewardCalculator = rewardCalculatorFactory.create(stakingOption, electedValidatorExposures, validatorPrefs, scope)
|
||||
val maxNominators = stakingConstantsRepository.maxRewardedNominatorPerValidator(chainId)
|
||||
val maxNominators = stakingConstantsRepository.maxRewardedNominatorPerValidator(stakingChainId)
|
||||
|
||||
return requestedValidatorIds.map { accountIdHex ->
|
||||
val accountId = AccountIdKey.fromHex(accountIdHex).getOrThrow()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"chainId": "bb4a61ab0c4b8c12f5eab71d0c86c482e03a275ecdafee678dea712474d33d75",
|
||||
"chainId": "1aa94987791a5544e9667ec249d2cef1b8fdd6083c85b93fc37892d54a1156ca",
|
||||
"name": "Pezkuwi",
|
||||
"icon": "https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/main/icons/tokens/colored/HEZ.svg",
|
||||
"addressPrefix": 42,
|
||||
@@ -72,13 +72,13 @@
|
||||
"feeViaRuntimeCall": true,
|
||||
"disabledCheckMetadataHash": true,
|
||||
"stakingMaxElectingVoters": 22500,
|
||||
"identityChain": "58269e9c184f721e0309332d90cafc410df1519a5dc27a5fd9b3bf5fd2d129f8",
|
||||
"identityChain": "69a8d025ab7b63363935d7d9397e0f652826c94271c1bc55c4fdfe72cccf1cfa",
|
||||
"stakingWiki": "https://wiki.pezkuwichain.io/staking"
|
||||
}
|
||||
},
|
||||
{
|
||||
"chainId": "00d0e1d0581c3cd5c5768652d52f4520184018b44f56a2ae1e0dc9d65c00c948",
|
||||
"parentId": "bb4a61ab0c4b8c12f5eab71d0c86c482e03a275ecdafee678dea712474d33d75",
|
||||
"chainId": "e7c15092dcbe3f320260ddbbc685bfceed9125a3b3d8436db2766201dec3b949",
|
||||
"parentId": "1aa94987791a5544e9667ec249d2cef1b8fdd6083c85b93fc37892d54a1156ca",
|
||||
"name": "Pezkuwi Asset Hub",
|
||||
"icon": "https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/main/icons/tokens/colored/PEZ.svg",
|
||||
"addressPrefix": 42,
|
||||
@@ -225,15 +225,15 @@
|
||||
"disabledCheckMetadataHash": true,
|
||||
"relaychainAsNative": true,
|
||||
"stakingMaxElectingVoters": 22500,
|
||||
"identityChain": "58269e9c184f721e0309332d90cafc410df1519a5dc27a5fd9b3bf5fd2d129f8",
|
||||
"timelineChain": "bb4a61ab0c4b8c12f5eab71d0c86c482e03a275ecdafee678dea712474d33d75",
|
||||
"identityChain": "69a8d025ab7b63363935d7d9397e0f652826c94271c1bc55c4fdfe72cccf1cfa",
|
||||
"timelineChain": "1aa94987791a5544e9667ec249d2cef1b8fdd6083c85b93fc37892d54a1156ca",
|
||||
"defaultBlockTime": 6000,
|
||||
"stakingWiki": "https://wiki.pezkuwichain.io/staking"
|
||||
}
|
||||
},
|
||||
{
|
||||
"chainId": "58269e9c184f721e0309332d90cafc410df1519a5dc27a5fd9b3bf5fd2d129f8",
|
||||
"parentId": "bb4a61ab0c4b8c12f5eab71d0c86c482e03a275ecdafee678dea712474d33d75",
|
||||
"chainId": "69a8d025ab7b63363935d7d9397e0f652826c94271c1bc55c4fdfe72cccf1cfa",
|
||||
"parentId": "1aa94987791a5544e9667ec249d2cef1b8fdd6083c85b93fc37892d54a1156ca",
|
||||
"name": "Pezkuwi People",
|
||||
"icon": "https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/main/icons/chains/PezkuwiPeople.png",
|
||||
"addressPrefix": 42,
|
||||
|
||||
Reference in New Issue
Block a user