Skip to content

Commit

Permalink
L1-63: Check front end after 1.3.0 and 1.4.0 and 1.5.0 and 1.6.0 (#125)
Browse files Browse the repository at this point in the history
Update azero.dev with upstream, split in 7 commit:
* Add upstream merge changes - some resolved, some unresolved
* Resolve typesBundle
* Resolve apps-config
* Resolve package.jsons, page-accounts, page-addresses, react-components
and react-signer
* Resolve page-staking
* Resolve pin.json, update translation, yarn.lock, package.json and
other
* Remove idealStake

Last one is debatable - I didn't know what an ideal stake would be on
Aleph Zero, I'll try to figure out it this metric makes sense and if it
does I'll revert last commit.
  • Loading branch information
Marcin-Radecki authored Oct 31, 2024
2 parents 0bbce06 + 16fc304 commit 98808cd
Show file tree
Hide file tree
Showing 512 changed files with 20,294 additions and 6,113 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/auto-approve.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ jobs:
steps:
- uses: jacogr/action-approve@795afd1dd096a2071d7ec98740661af4e853b7da
with:
authors: jacogr
authors: jacogr, TarikGul
labels: -auto
token: ${{ secrets.GH_PAT_BOT }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ tmp/
.yarn/*
!.yarn/releases
!.yarn/plugins
!.yarn/patches
.pnp.*
cc-test-reporter
package-lock.json
Expand Down
202 changes: 202 additions & 0 deletions .yarn/patches/@polkadot-api-derive-npm-13.2.1-19d2cc1087.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
diff --git a/cjs/staking/query.js b/cjs/staking/query.js
index 24826c714d1c6609d65ec379c385e9331e9e30cf..04d90275bfd3731d876629845d2a5fc183b0c01e 100644
--- a/cjs/staking/query.js
+++ b/cjs/staking/query.js
@@ -54,11 +54,17 @@ function filterRewards(stashIds, eras, claimedRewards, stakersOverview) {
? era
: -1;
}
+ // There is an migration period of 84 eras, where historical validators are still kept under `erasStakers`,
+ // but rewards are getting stored under `claimedRewards`. At least one page needs to be claimed.
+ if (rewardsPerEra && rewardsPerEra.has(era) && (!overviewPerEra || !overviewPerEra.has(era))) {
+ const rewards = rewardsPerEra.get(era);
+ return rewards.length > 0 ? era : -1;
+ }
return -1;
});
});
}
-function parseDetails(api, stashId, controllerIdOpt, nominatorsOpt, rewardDestinationOpts, validatorPrefs, exposure, stakingLedgerOpt, exposureMeta, claimedRewards, exposureEraStakers) {
+function parseDetails(api, stashId, controllerIdOpt, nominatorsOpt, rewardDestinationOpts, validatorPrefs, exposure, stakingLedgerOpt, exposureMeta, claimedRewards, exposureEraStakers, allOtherNominators) {
return {
accountId: stashId,
claimedRewardsEras: filterClaimedRewards(api, claimedRewards),
@@ -72,8 +78,11 @@ function parseDetails(api, stashId, controllerIdOpt, nominatorsOpt, rewardDestin
rewardDestination: rewardDestinationCompat(rewardDestinationOpts),
stakingLedger: stakingLedgerOpt.unwrapOrDefault(),
stashId,
- validatorPrefs
- };
+ validatorPrefs,
+ // Expose validators' all nominators. It used to be done by `erasStakers`, but now requires combining entries
+ // from all pages of `erasStakersPaged` which is cumbersome to do on frontend.
+ allOtherNominators
+};
}
function getLedgers(api, optIds, { withLedger = false }) {
const ids = optIds
@@ -133,11 +142,28 @@ function getStashInfo(api, stashIds, activeEra, { withClaimedRewardsEras, withCo
: (0, rxjs_1.of)(stashIds.map(() => emptyClaimedRewards)),
withExposureErasStakersLegacy && api.query.staking.erasStakers
? (0, rxjs_1.combineLatest)(stashIds.map((s) => api.query.staking.erasStakers(activeEra, s)))
- : (0, rxjs_1.of)(stashIds.map(() => emptyExpoEraStakers))
+ : (0, rxjs_1.of)(stashIds.map(() => emptyExpoEraStakers)),
+ // Expose validators' all nominators. It used to be done by `erasStakers`, but now requires combining entries
+ // from all pages of `erasStakersPaged` which is cumbersome to do on frontend.
+ withExposure && api.query.staking.erasStakersPaged
+ ? (0, rxjs_1.combineLatest)(
+ stashIds.map(
+ (s) => api.query.staking.erasStakersPaged.entries(activeEra, s).pipe(
+ (0, rxjs_1.map)((exposurePagedAll) => exposurePagedAll.flatMap(([_, exposurePage]) => exposurePage.unwrapOrDefault().others)),
+ (0, rxjs_1.switchMap)((allOtherNominators) => allOtherNominators.length === 0 && api.query.staking.erasStakers
+ ? api.query.staking.erasStakers(activeEra, s).pipe(
+ (0, rxjs_1.map)((erasStakers) => erasStakers.others)
+ )
+ : of(allOtherNominators)
+ ),
+ )
+ )
+ )
+ : (0, rxjs_1.of)(stashIds.map(() => [])),
]);
}
function getBatch(api, activeEra, stashIds, flags, page) {
- return getStashInfo(api, stashIds, activeEra, flags, page).pipe((0, rxjs_1.switchMap)(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure, exposureMeta, claimedRewardsEras, exposureEraStakers]) => getLedgers(api, controllerIdOpt, flags).pipe((0, rxjs_1.map)((stakingLedgerOpts) => stashIds.map((stashId, index) => parseDetails(api, stashId, controllerIdOpt[index], nominatorsOpt[index], rewardDestination[index], validatorPrefs[index], exposure[index], stakingLedgerOpts[index], exposureMeta[index], claimedRewardsEras[index], exposureEraStakers[index]))))));
+ return getStashInfo(api, stashIds, activeEra, flags, page).pipe((0, rxjs_1.switchMap)(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure, exposureMeta, claimedRewardsEras, exposureEraStakers, allOtherNominators]) => getLedgers(api, controllerIdOpt, flags).pipe((0, rxjs_1.map)((stakingLedgerOpts) => stashIds.map((stashId, index) => parseDetails(api, stashId, controllerIdOpt[index], nominatorsOpt[index], rewardDestination[index], validatorPrefs[index], exposure[index], stakingLedgerOpts[index], exposureMeta[index], claimedRewardsEras[index], exposureEraStakers[index], allOtherNominators[index]))))));
}
/**
* @description From a stash, retrieve the controllerId and all relevant details
diff --git a/cjs/staking/validators.js b/cjs/staking/validators.js
index 5d74f9b00630b7cbfe1fbab5cf584b18465be262..6261b5b397528ca376c6b60fbd4c28e581c780af 100644
--- a/cjs/staking/validators.js
+++ b/cjs/staking/validators.js
@@ -7,11 +7,16 @@ const index_js_1 = require("../util/index.js");
function nextElected(instanceId, api) {
return (0, index_js_1.memo)(instanceId, () =>
// Compatibility for future generation changes in staking.
- api.query.staking.erasStakersPaged
+ // Use `erasStakersOverview` instead of `erasStakersPaged` to get all era's validators instead of
+ // era's validators nominated by at least one other nominator.
+ api.query.staking.erasStakersOverview
? api.derive.session.indexes().pipe(
// only populate for next era in the last session, so track both here - entries are not
// subscriptions, so we need a trigger - currentIndex acts as that trigger to refresh
- (0, rxjs_1.switchMap)(({ currentEra }) => api.query.staking.erasStakersPaged.keys(currentEra)),
+ (0, rxjs_1.switchMap)(({ currentEra }) => api.query.staking.erasStakersOverview.keys(currentEra).pipe(map((keys) => [keys, currentEra]))),
+ // Even though `erasStakersOverview` is defined it might not be populated.
+ // We check if `erasStakersOverview` storage has been populated and fallback to `erasStakers` if not.
+ (0, rxjs_1.switchMap)(([keys, currentEra]) => keys.length === 0 && api.query.staking.erasStakers ? api.query.staking.erasStakers.keys(currentEra) : of(keys)),
// Dedupe any duplicates
(0, rxjs_1.map)((keys) => [...new Set(keys.map(({ args: [, accountId] }) => accountId.toString()))].map((a) => api.registry.createType('AccountId', a))))
: api.query.staking.erasStakers
diff --git a/staking/query.js b/staking/query.js
index f9448e7b554df170c96971eccbe0c3c94f0fd695..e01c0ad9cf72e9d082c3de610d03c0732bbfda06 100644
--- a/staking/query.js
+++ b/staking/query.js
@@ -50,11 +50,17 @@ function filterRewards(stashIds, eras, claimedRewards, stakersOverview) {
? era
: -1;
}
+ // There is an migration period of 84 eras, where historical validators are still kept under `erasStakers`,
+ // but rewards are getting stored under `claimedRewards`. At least one page needs to be claimed.
+ if (rewardsPerEra && rewardsPerEra.has(era) && (!overviewPerEra || !overviewPerEra.has(era))) {
+ const rewards = rewardsPerEra.get(era);
+ return rewards.length > 0 ? era : -1;
+ }
return -1;
});
});
}
-function parseDetails(api, stashId, controllerIdOpt, nominatorsOpt, rewardDestinationOpts, validatorPrefs, exposure, stakingLedgerOpt, exposureMeta, claimedRewards, exposureEraStakers) {
+function parseDetails(api, stashId, controllerIdOpt, nominatorsOpt, rewardDestinationOpts, validatorPrefs, exposure, stakingLedgerOpt, exposureMeta, claimedRewards, exposureEraStakers, allOtherNominators) {
return {
accountId: stashId,
claimedRewardsEras: filterClaimedRewards(api, claimedRewards),
@@ -68,8 +74,11 @@ function parseDetails(api, stashId, controllerIdOpt, nominatorsOpt, rewardDestin
rewardDestination: rewardDestinationCompat(rewardDestinationOpts),
stakingLedger: stakingLedgerOpt.unwrapOrDefault(),
stashId,
- validatorPrefs
- };
+ validatorPrefs,
+ // Expose validators' all nominators. It used to be done by `erasStakers`, but now requires combining entries
+ // from all pages of `erasStakersPaged` which is cumbersome to do on frontend.
+ allOtherNominators
+};
}
function getLedgers(api, optIds, { withLedger = false }) {
const ids = optIds
@@ -129,11 +138,28 @@ function getStashInfo(api, stashIds, activeEra, { withClaimedRewardsEras, withCo
: of(stashIds.map(() => emptyClaimedRewards)),
withExposureErasStakersLegacy && api.query.staking.erasStakers
? combineLatest(stashIds.map((s) => api.query.staking.erasStakers(activeEra, s)))
- : of(stashIds.map(() => emptyExpoEraStakers))
+ : of(stashIds.map(() => emptyExpoEraStakers)),
+ // Expose validators' all nominators. It used to be done by `erasStakers`, but now requires combining entries
+ // from all pages of `erasStakersPaged` which is cumbersome to do on frontend.
+ withExposure && api.query.staking.erasStakersPaged
+ ? combineLatest(
+ stashIds.map(
+ (s) => api.query.staking.erasStakersPaged.entries(activeEra, s).pipe(
+ map((exposurePagedAll) => exposurePagedAll.flatMap(([_, exposurePage]) => exposurePage.unwrapOrDefault().others)),
+ switchMap((allOtherNominators) => allOtherNominators.length === 0 && api.query.staking.erasStakers
+ ? api.query.staking.erasStakers(activeEra, s).pipe(
+ map((erasStakers) => erasStakers.others)
+ )
+ : of(allOtherNominators)
+ ),
+ )
+ )
+ )
+ : of(stashIds.map(() => [])),
]);
}
function getBatch(api, activeEra, stashIds, flags, page) {
- return getStashInfo(api, stashIds, activeEra, flags, page).pipe(switchMap(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure, exposureMeta, claimedRewardsEras, exposureEraStakers]) => getLedgers(api, controllerIdOpt, flags).pipe(map((stakingLedgerOpts) => stashIds.map((stashId, index) => parseDetails(api, stashId, controllerIdOpt[index], nominatorsOpt[index], rewardDestination[index], validatorPrefs[index], exposure[index], stakingLedgerOpts[index], exposureMeta[index], claimedRewardsEras[index], exposureEraStakers[index]))))));
+ return getStashInfo(api, stashIds, activeEra, flags, page).pipe(switchMap(([controllerIdOpt, nominatorsOpt, rewardDestination, validatorPrefs, exposure, exposureMeta, claimedRewardsEras, exposureEraStakers, allOtherNominators]) => getLedgers(api, controllerIdOpt, flags).pipe(map((stakingLedgerOpts) => stashIds.map((stashId, index) => parseDetails(api, stashId, controllerIdOpt[index], nominatorsOpt[index], rewardDestination[index], validatorPrefs[index], exposure[index], stakingLedgerOpts[index], exposureMeta[index], claimedRewardsEras[index], exposureEraStakers[index], allOtherNominators[index]))))));
}
/**
* @description From a stash, retrieve the controllerId and all relevant details
diff --git a/staking/types.d.ts b/staking/types.d.ts
index 74e54287d69b3cfc7c9713cd744737bc7ac1078f..4dd7d49cb6baf9fea6f4b99e7cf91b40c0b4d2b0 100644
--- a/staking/types.d.ts
+++ b/staking/types.d.ts
@@ -1,6 +1,6 @@
import type { Option, u32, Vec } from '@polkadot/types';
import type { AccountId, Balance, EraIndex, RewardPoint } from '@polkadot/types/interfaces';
-import type { PalletStakingRewardDestination, PalletStakingStakingLedger, PalletStakingValidatorPrefs, SpStakingExposure, SpStakingExposurePage, SpStakingPagedExposureMetadata } from '@polkadot/types/lookup';
+import type { PalletStakingRewardDestination, PalletStakingStakingLedger, PalletStakingValidatorPrefs, SpStakingExposure, SpStakingExposurePage, SpStakingPagedExposureMetadata, SpStakingIndividualExposure } from '@polkadot/types/lookup';
import type { BN } from '@polkadot/util';
import type { DeriveSessionIndexes } from '../session/types.js';
export type DeriveEraValPoints = Record<string, RewardPoint>;
@@ -99,6 +99,7 @@ export interface DeriveStakingStash {
stashId: AccountId;
validatorPrefs: PalletStakingValidatorPrefs;
claimedRewardsEras: Vec<u32>;
+ allOtherNominators: Vec<SpStakingIndividualExposure>;
}
export interface DeriveStakingQuery extends DeriveStakingStash {
accountId: AccountId;
diff --git a/staking/validators.js b/staking/validators.js
index bfaae2c0e0da493cc09b60fbb45ad9ceef0faf27..5eefaa5cc48e47aaa2e082e744848784f00704f1 100644
--- a/staking/validators.js
+++ b/staking/validators.js
@@ -3,11 +3,16 @@ import { memo } from '../util/index.js';
export function nextElected(instanceId, api) {
return memo(instanceId, () =>
// Compatibility for future generation changes in staking.
- api.query.staking.erasStakersPaged
+ // Use `erasStakersOverview` instead of `erasStakersPaged` to get all era's validators instead of
+ // era's validators nominated by at least one other nominator.
+ api.query.staking.erasStakersOverview
? api.derive.session.indexes().pipe(
// only populate for next era in the last session, so track both here - entries are not
// subscriptions, so we need a trigger - currentIndex acts as that trigger to refresh
- switchMap(({ currentEra }) => api.query.staking.erasStakersPaged.keys(currentEra)),
+ switchMap(({ currentEra }) => api.query.staking.erasStakersOverview.keys(currentEra).pipe(map((keys) => [keys, currentEra]))),
+ // Even though `erasStakersOverview` is defined it might not be populated.
+ // We check if `erasStakersOverview` storage has been populated and fallback to `erasStakers` if not.
+ switchMap(([keys, currentEra]) => keys.length === 0 && api.query.staking.erasStakers ? api.query.staking.erasStakers.keys(currentEra) : of(keys)),
// Dedupe any duplicates
map((keys) => [...new Set(keys.map(({ args: [, accountId] }) => accountId.toString()))].map((a) => api.registry.createType('AccountId', a))))
: api.query.staking.erasStakers
Loading

0 comments on commit 98808cd

Please sign in to comment.