Skip to content

Commit

Permalink
Merge pull request #1513 from novasamatech/rc/7.12.1
Browse files Browse the repository at this point in the history
Rc/7.12.1
  • Loading branch information
valentunn committed May 16, 2024
2 parents 9c6efd6 + 187baa5 commit 09e7510
Show file tree
Hide file tree
Showing 22 changed files with 102 additions and 41 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
buildscript {
ext {
// App version
versionName = '7.12.0'
versionCode = 132
versionName = '7.12.1'
versionCode = 133

applicationId = "io.novafoundation.nova"
releaseApplicationSuffix = "market"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,11 @@ inline fun <T> ExtendedLoadingState<T>.onNotLoaded(action: () -> Unit): Extended

return this
}

inline fun <T> ExtendedLoadingState<T>.onError(action: (Throwable) -> Unit): ExtendedLoadingState<T> {
if (this is ExtendedLoadingState.Error) {
action(exception)
}

return this
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package io.novafoundation.nova.feature_staking_impl.data.nominationPools.repository

import io.novafoundation.nova.common.utils.orZero
import io.novafoundation.nova.feature_staking_api.domain.nominationPool.model.PoolId
import io.novafoundation.nova.feature_staking_impl.data.nominationPools.datasource.KnownMaxUnlockingOverwrites
import io.novafoundation.nova.feature_staking_impl.data.nominationPools.network.blockhain.api.counterForPoolMembers
import io.novafoundation.nova.feature_staking_impl.data.nominationPools.network.blockhain.api.lastPoolId
import io.novafoundation.nova.feature_staking_impl.data.nominationPools.network.blockhain.api.maxPoolMembers
import io.novafoundation.nova.feature_staking_impl.data.nominationPools.network.blockhain.api.maxPoolMembersPerPool
import io.novafoundation.nova.feature_staking_impl.data.nominationPools.network.blockhain.api.minJoinBond
import io.novafoundation.nova.feature_staking_impl.data.nominationPools.network.blockhain.api.nominationPools
import io.novafoundation.nova.feature_staking_api.domain.nominationPool.model.PoolId
import io.novafoundation.nova.feature_staking_impl.data.repository.StakingConstantsRepository
import io.novafoundation.nova.feature_wallet_api.data.network.blockhain.types.Balance
import io.novafoundation.nova.runtime.multiNetwork.chain.model.ChainId
Expand Down Expand Up @@ -56,7 +56,7 @@ class RealNominationPoolGlobalsRepository(
return localStorageDataSource.query(chainId) {
val poolIdRaw = metadata.nominationPools.lastPoolId.query()

PoolId(poolIdRaw!!)
PoolId(poolIdRaw.orZero())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.withContext
import java.math.BigInteger
import kotlinx.coroutines.flow.map

class StakingRepositoryImpl(
private val accountStakingDao: AccountStakingDao,
Expand Down Expand Up @@ -136,11 +135,17 @@ class StakingRepositoryImpl(
binding = { instance, _ -> bindExposureOverview(instance) }
)

val eraStakersPaged = runtime.metadata.staking().storage("ErasStakersPaged").entries(
eraIndex,
keyExtractor = { (_: BigInteger, accountId: ByteArray, page: BigInteger) -> accountId.toHexString() to page.toInt() },
binding = { instance, _ -> bindExposurePage(instance) }
)
val atLeastOneNominatorPresent = eraStakersOverview.any { (_, exposureOverview) -> exposureOverview.nominatorCount > BigInteger.ZERO }

val eraStakersPaged = if (atLeastOneNominatorPresent) {
runtime.metadata.staking().storage("ErasStakersPaged").entries(
eraIndex,
keyExtractor = { (_: BigInteger, accountId: ByteArray, page: BigInteger) -> accountId.toHexString() to page.toInt() },
binding = { instance, _ -> bindExposurePage(instance) }
)
} else {
emptyMap()
}

mergeOverviewsAndPagedOthers(eraStakersOverview, eraStakersPaged)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import io.novasama.substrate_sdk_android.wsrpc.executeAsync
import io.novasama.substrate_sdk_android.wsrpc.mappers.nonNull
import io.novasama.substrate_sdk_android.wsrpc.mappers.pojo
import io.novasama.substrate_sdk_android.wsrpc.request.runtime.RuntimeRequest
import java.math.BigInteger
import java.math.BigDecimal

interface VaraRepository {

Expand All @@ -22,7 +22,9 @@ class RealVaraRepository(
) : VaraRepository {

override suspend fun getVaraInflation(chainId: ChainId): Perbill {
return chainRegistry.getSocket(chainId).inflationInfo().inflation.asPerQuintill()
return chainRegistry.getSocket(chainId).inflationInfo().inflation
.toBigInteger()
.asPerQuintill()
}

private suspend fun SocketService.inflationInfo(): InflationInfo {
Expand All @@ -34,5 +36,5 @@ class RealVaraRepository(
params = emptyList()
)

private class InflationInfo(val inflation: BigInteger)
private class InflationInfo(val inflation: BigDecimal)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ interface NominationPoolRecommender {

val recommendations: List<NominationPool>

fun recommendedPool(): NominationPool
fun recommendedPool(): NominationPool?
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ private class RealNominationPoolRecommender(

override val recommendations = constructRecommendationList()

override fun recommendedPool(): NominationPool {
return recommendations.first()
override fun recommendedPool(): NominationPool? {
return recommendations.firstOrNull()
}

private fun constructRecommendationList(): List<NominationPool> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.novafoundation.nova.feature_staking_impl.domain.recommendations

import io.novafoundation.nova.common.utils.applyFilters
import io.novafoundation.nova.feature_staking_api.domain.model.Validator
import io.novafoundation.nova.feature_staking_impl.domain.recommendations.settings.RecommendationFilter
import io.novafoundation.nova.feature_staking_impl.domain.recommendations.settings.RecommendationSettings
import io.novafoundation.nova.feature_staking_impl.domain.recommendations.settings.RecommendationSorting
import kotlinx.coroutines.Dispatchers
Expand All @@ -13,7 +14,7 @@ class ValidatorRecommender(
) {

suspend fun recommendations(settings: RecommendationSettings) = withContext(Dispatchers.Default) {
val all = availableValidators.applyFilters(settings.allFilters)
val all = availableValidators.applyFiltersAdaptingToEmptyResult(settings.allFilters)
.sortedWith(settings.sorting)

val postprocessed = settings.postProcessors.fold(all) { acc, postProcessor ->
Expand All @@ -37,4 +38,16 @@ class ValidatorRecommender(

return (cappedNovaValidators + cappedOthers).sortedWith(sorting)
}

private fun List<Validator>.applyFiltersAdaptingToEmptyResult(filters: List<RecommendationFilter>): List<Validator> {
var filtered = applyFilters(filters)

if (filtered.isEmpty()) {
val weakenedFilters = filters.filterNot { it.canIgnoreWhenNoApplicableCandidatesFound() }

filtered = applyFilters(weakenedFilters)
}

return filtered
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import io.novafoundation.nova.common.utils.PalletBasedFilter
import io.novafoundation.nova.common.utils.RuntimeDependent
import io.novafoundation.nova.feature_staking_api.domain.model.Validator

typealias RecommendationFilter = PalletBasedFilter<Validator>
interface RecommendationFilter : PalletBasedFilter<Validator> {

fun canIgnoreWhenNoApplicableCandidatesFound(): Boolean
}

typealias RecommendationSorting = Comparator<Validator>

interface RecommendationPostProcessor : RuntimeDependent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ object HasIdentityFilter : RecommendationFilter {
return model.identity != null
}

override fun canIgnoreWhenNoApplicableCandidatesFound(): Boolean {
return true
}

override fun availableIn(runtime: RuntimeSnapshot): Boolean {
return runtime.metadata.hasModule(Modules.IDENTITY)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ import io.novafoundation.nova.feature_staking_impl.domain.recommendations.settin

object NotBlockedFilter : RecommendationFilter {

override fun canIgnoreWhenNoApplicableCandidatesFound(): Boolean {
return false
}

override fun shouldInclude(model: Validator) = model.prefs?.blocked?.not() ?: false
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import io.novafoundation.nova.feature_staking_impl.domain.recommendations.settin

object NotOverSubscribedFilter : RecommendationFilter {

override fun canIgnoreWhenNoApplicableCandidatesFound(): Boolean {
return true
}

override fun shouldInclude(model: Validator): Boolean {
val isOversubscribed = model.electedInfo?.isOversubscribed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import io.novafoundation.nova.feature_staking_impl.domain.recommendations.settin

object NotSlashedFilter : RecommendationFilter {

override fun canIgnoreWhenNoApplicableCandidatesFound(): Boolean {
return true
}

override fun shouldInclude(model: Validator): Boolean {
return !model.slashed
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class VaraRewardCalculator(
) : InflationBasedRewardCalculator(validators, totalIssuance) {

override fun calculateYearlyInflation(stakedPortion: Double): Double {
return inflation.value
// When calculating era payout, Vara runtime simply divides yearly payout by number of eras in the year
// Which results in `inflation` to correspond to simple returns (APR)
// So, we adjust it to compound returns (APY)
return aprToApy(inflation.value)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ interface SingleStakingProperties {

interface SingleStakingRecommendation {

suspend fun recommendedSelection(stake: Balance): StartMultiStakingSelection
suspend fun recommendedSelection(stake: Balance): StartMultiStakingSelection?
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class NominationPoolRecommendation(
nominationPoolRecommenderFactory.create(stakingOption, scope)
}

override suspend fun recommendedSelection(stake: Balance): StartMultiStakingSelection {
val recommendedPool = recommendator.await().recommendedPool()
override suspend fun recommendedSelection(stake: Balance): StartMultiStakingSelection? {
val recommendedPool = recommendator.await().recommendedPool() ?: return null

return NominationPoolSelection(recommendedPool, stakingOption, stake)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class AutomaticMultiStakingSelectionType(
}

override suspend fun updateSelectionFor(stake: Balance) {
val selection = selectionFor(stake)
val selection = selectionFor(stake) ?: return

val recommendableSelection = RecommendableMultiStakingSelection(
source = SelectionTypeSource.Automatic,
selection = selection
Expand All @@ -49,7 +50,7 @@ class AutomaticMultiStakingSelectionType(
selectionStore.updateSelection(recommendableSelection)
}

private suspend fun selectionFor(stake: Balance): StartMultiStakingSelection {
private suspend fun selectionFor(stake: Balance): StartMultiStakingSelection? {
val candidate = candidates.firstAllowingToStake(stake) ?: candidates.findWithMinimumStake()

return candidate.recommendation.recommendedSelection(stake)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.novafoundation.nova.feature_staking_impl.domain.staking.start.setupStakingType

import androidx.lifecycle.viewModelScope
import io.novafoundation.nova.feature_staking_api.domain.model.Validator
import io.novafoundation.nova.feature_staking_impl.data.StakingOption
import io.novafoundation.nova.feature_staking_impl.domain.nominationPools.model.NominationPool
Expand All @@ -12,10 +11,10 @@ import io.novafoundation.nova.feature_staking_impl.domain.staking.start.common.s
import io.novafoundation.nova.feature_staking_impl.domain.staking.start.setupAmount.SingleStakingPropertiesFactory
import io.novafoundation.nova.feature_staking_impl.domain.staking.start.setupAmount.direct.DirectStakingSelection
import io.novafoundation.nova.feature_staking_impl.domain.staking.start.setupAmount.pools.NominationPoolSelection
import java.math.BigInteger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import java.math.BigInteger

class SetupStakingTypeSelectionMixinFactory(
private val currentSelectionStoreProvider: StartMultiStakingSelectionStoreProvider,
Expand Down Expand Up @@ -68,10 +67,13 @@ class SetupStakingTypeSelectionMixin(
.recommendation
.recommendedSelection(selection.stake)

// Content is not recommended if recommendation does not exist
val contentRecommended = recommendedSelection?.isSettingsEquals(selection) ?: false

currentSelectionStoreProvider.getSelectionStore(scope)
.updateSelection(
RecommendableMultiStakingSelection(
SelectionTypeSource.Manual(contentRecommended = recommendedSelection.isSettingsEquals(selection)),
SelectionTypeSource.Manual(contentRecommended = contentRecommended),
selection
)
)
Expand All @@ -80,7 +82,7 @@ class SetupStakingTypeSelectionMixin(
suspend fun selectRecommended(viewModelScope: CoroutineScope, stakingOption: StakingOption, amount: BigInteger) {
val recommendedSelection = singleStakingPropertiesFactory.createProperties(scope, stakingOption)
.recommendation
.recommendedSelection(amount)
.recommendedSelection(amount) ?: return

val recommendableMultiStakingSelection = RecommendableMultiStakingSelection(
source = SelectionTypeSource.Manual(contentRecommended = true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import io.novafoundation.nova.feature_staking_impl.presentation.pools.common.Poo
import io.novafoundation.nova.feature_staking_impl.presentation.pools.common.SelectingPoolPayload
import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry
import io.novafoundation.nova.runtime.multiNetwork.chainWithAsset
import java.math.BigInteger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import java.math.BigInteger

class SelectPoolViewModel(
private val router: StakingRouter,
Expand Down Expand Up @@ -68,7 +68,9 @@ class SelectPoolViewModel(

val fillWithRecommendedEnabled = combine(nominationPoolRecommenderFlow, editableSelection) { recommender, selection ->
val selectedPool = selection.selection.asPoolSelection()?.pool
recommender.recommendedPool().id != selectedPool?.id
val recommendedPool = recommender.recommendedPool()

recommendedPool != null && recommendedPool.id != selectedPool?.id
}
.share()

Expand Down Expand Up @@ -99,7 +101,7 @@ class SelectPoolViewModel(

fun selectRecommended() {
launch {
val recommendedPool = nominationPoolRecommenderFlow.first().recommendedPool()
val recommendedPool = nominationPoolRecommenderFlow.first().recommendedPool() ?: return@launch
setupStakingTypeSelectionMixin.selectNominationPoolAndApply(recommendedPool, stakingOption())
router.finishSetupPoolFlow()
}
Expand Down

0 comments on commit 09e7510

Please sign in to comment.