Add new staking types, support derives (#1828)

* Add new staking types

* StakingLedgerTo213 - StakingLedgerTo223

* StakingLedgerTo223 in polkadot (dev)

* Add derive activeEra

* Map Ponts -> RewardPoints

* StakingLedger override CHANGELOG

* Cleanups

* Apparent CC dupes (don't see it, but cleanup useul)

* Cleanup result formatting for indexes

* Map nextElected -> validators

* Fix StakingLedger to current

* Merge CHANGELOG

* Mention derive staking updates

* Mark derive changes as breaking
This commit is contained in:
Jaco Greeff
2020-02-24 16:52:48 +01:00
committed by GitHub
parent 64aa4dcc1c
commit cbc14cc291
14 changed files with 394 additions and 206 deletions
+2 -1
View File
@@ -1,13 +1,14 @@
# 1.4.0-beta.x
- **Breaking change** (TypeScript only) The `*.d.ts` files now contain TypeScript 3.8 features, `#private`, which is not usable in older versions
- **Breaking change** - `api.derive.staking.*` has updated result types and detects support for lazy payouts queries
- Add `api.rpc.chain.subscribeAllHeads` (not just best) (Thanks to https://github.com/jak-pan)
- Add `api.rpc.engine.*` for manual seal support
- Add `api.injectMetadata(metadata)` to initialize API with a specific metadata version
- The api now checks for runtime upgrades, augmenting the interfaces with new metadata when found
- Support types & interfaces required for lazy reaping, lazy payouts & offchain phragmen
- Support JS `BigInt` inputs in any derived `UInt` and `Int` object, `api.tx.balances.transfer(..., 9876543210123456789n)`
- Registry now exposes `.createType(<type>, ...args)` as an additional helper (like the API)
- Support types & interfaces required for lazy reaping & offchain phragmen
- Expand `.toHuman` on `ExtrinsicEra`, `SubmittableResult` & `Vote`
- Move `DigestItem`, `Fixed64`, `H160`, `H256` & `H512` to interfaces in `@polkadot/types/interfaces`
- Align construction of unknown types in `registry.get` consistently warn on detection, throw on use
+10 -16
View File
@@ -12,21 +12,6 @@ import { createType } from '@polkadot/types';
import { memo } from '../util';
type Result = [Balance, Balance, Balance, Balance, Balance];
function query (api: ApiInterfaceRx): Observable<Result> {
return of([
// deprecated - remove
(api.consts.balances.creationFee as Balance) || createType(api.registry, 'Balance'),
(api.consts.balances.transferFee as Balance) || createType(api.registry, 'Balance'),
// current
api.consts.balances.existentialDeposit,
api.consts.transactionPayment.transactionBaseFee,
api.consts.transactionPayment.transactionByteFee
]);
}
/**
* @name fees
* @returns An object containing the combined results of the storage queries for
@@ -42,7 +27,16 @@ function query (api: ApiInterfaceRx): Observable<Result> {
*/
export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
return memo((): Observable<DerivedFees> =>
query(api).pipe(
of([
// deprecated - remove
(api.consts.balances.creationFee as Balance) || createType(api.registry, 'Balance'),
(api.consts.balances.transferFee as Balance) || createType(api.registry, 'Balance'),
// current
api.consts.balances.existentialDeposit,
api.consts.transactionPayment.transactionBaseFee,
api.consts.transactionPayment.transactionByteFee
]).pipe(
map(([creationFee, transferFee, existentialDeposit, transactionBaseFee, transactionByteFee]): DerivedFees => ({
creationFee,
existentialDeposit,
+68 -14
View File
@@ -3,29 +3,83 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { EraIndex, SessionIndex } from '@polkadot/types/interfaces';
import { EraIndex, MomentOf, SessionIndex } from '@polkadot/types/interfaces';
import { DeriveSessionIndexes } from '../types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType, u32 as U32 } from '@polkadot/types';
import { createType, Option, u32 } from '@polkadot/types';
import { memo } from '../util';
type Result = [EraIndex, Option<MomentOf>, EraIndex, SessionIndex, u32];
// parse into Indexes
function parse ([activeEra, activeEraStart, currentEra, currentIndex, validatorCount]: Result): DeriveSessionIndexes {
return {
activeEra,
activeEraStart,
currentEra,
currentIndex,
validatorCount
};
}
// query for previous V2
function queryNoActive (api: ApiInterfaceRx): Observable<Result> {
return api.queryMulti<[EraIndex, SessionIndex, u32]>([
api.query.staking.currentEra,
api.query.session.currentIndex,
api.query.staking.validatorCount
]).pipe(
map(([currentEra, currentIndex, validatorCount]): Result => [
currentEra,
createType(api.registry, 'Option<MomentOf>'),
currentEra,
currentIndex,
validatorCount
])
);
}
// query based on latest
function query (api: ApiInterfaceRx): Observable<Result> {
return api.queryMulti<[Option<EraIndex>, Option<MomentOf>, Option<EraIndex>, SessionIndex, u32]>([
api.query.staking.activeEra,
api.query.staking.activeEraStart,
api.query.staking.currentEra,
api.query.session.currentIndex,
api.query.staking.validatorCount
]).pipe(
map(([activeEra, activeEraStart, currentEra, currentIndex, validatorCount]): Result => [
activeEra.unwrapOr(createType(api.registry, 'EraIndex', 1)),
activeEraStart,
currentEra.unwrapOr(createType(api.registry, 'EraIndex', 1)),
currentIndex,
validatorCount
])
);
}
// empty set when none is available
function empty (api: ApiInterfaceRx): Observable<Result> {
return of([
createType(api.registry, 'EraIndex', 1),
createType(api.registry, 'Option<MomentOf>'),
createType(api.registry, 'EraIndex', 1),
createType(api.registry, 'SessionIndex', 1),
createType(api.registry, 'u32')
]);
}
export function indexes (api: ApiInterfaceRx): () => Observable<DeriveSessionIndexes> {
return memo((): Observable<DeriveSessionIndexes> =>
(
// Some chains (eg. very limited node-template), does not have session
api.query.session && api.query.staking
? api.queryMulti<[SessionIndex, EraIndex, U32]>([
api.query.session.currentIndex,
api.query.staking.currentEra,
api.query.staking.validatorCount
])
: of([createType(api.registry, 'SessionIndex', 1), createType(api.registry, 'EraIndex', 1), createType(api.registry, 'u32')])
).pipe(
map(([currentIndex, currentEra, validatorCount]): DeriveSessionIndexes => ({
currentIndex, currentEra, validatorCount
}))
));
? api.query.staking.activeEra
? query(api)
: queryNoActive(api)
: empty(api)
).pipe(map(parse))
);
}
+61 -28
View File
@@ -5,23 +5,26 @@
import { SessionIndex } from '@polkadot/types/interfaces';
import { DerivedSessionInfo, DeriveSessionIndexes } from '../types';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { u64, createType } from '@polkadot/types';
import { createType, Option, u64 } from '@polkadot/types';
import { memo } from '../util';
type ResultSlots = [u64, u64, u64, SessionIndex];
type ResultSlots = [u64, u64, u64, Option<SessionIndex>];
type ResultSlotsFlat = [u64, u64, u64, SessionIndex];
type ResultType = [boolean, u64, SessionIndex];
type Result = [ResultType, DeriveSessionIndexes, ResultSlots];
type Result = [ResultType, DeriveSessionIndexes, ResultSlotsFlat];
function createDerivedLatest (api: ApiInterfaceRx, [[hasBabe, epochDuration, sessionsPerEra], { currentIndex, currentEra, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, currentEraStartSessionIndex]]: Result): DerivedSessionInfo {
function createDerived (api: ApiInterfaceRx, [[hasBabe, epochDuration, sessionsPerEra], { activeEra, activeEraStart, currentEra, currentIndex, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, activeEraStartSessionIndex]]: Result): DerivedSessionInfo {
const epochStartSlot = epochIndex.mul(epochDuration).add(epochOrGenesisStartSlot);
const sessionProgress = currentSlot.sub(epochStartSlot);
const eraProgress = currentIndex.sub(currentEraStartSessionIndex).mul(epochDuration).add(sessionProgress);
const eraProgress = currentIndex.sub(activeEraStartSessionIndex).mul(epochDuration).add(sessionProgress);
return {
activeEra,
activeEraStart,
currentEra,
currentIndex,
eraLength: createType(api.registry, 'BlockNumber', sessionsPerEra.mul(epochDuration)),
@@ -34,46 +37,76 @@ function createDerivedLatest (api: ApiInterfaceRx, [[hasBabe, epochDuration, ses
};
}
function infoLatestAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
function queryAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
return api.derive.session.indexes().pipe(
map((indexes): DerivedSessionInfo =>
createDerivedLatest(api, [
[false, createType(api.registry, 'u64', 1), api.consts.staking?.sessionsPerEra || createType(api.registry, 'SessionIndex', 1)],
createDerived(api, [
[
false,
createType(api.registry, 'u64', 1),
api.consts.staking?.sessionsPerEra || createType(api.registry, 'SessionIndex', 1)
],
indexes,
[createType(api.registry, 'u64', 1), createType(api.registry, 'u64', 1), createType(api.registry, 'u64', 1), createType(api.registry, 'SessionIndex', 1)]
[
createType(api.registry, 'u64', 1),
createType(api.registry, 'u64', 1),
createType(api.registry, 'u64', 1),
createType(api.registry, 'SessionIndex', 1)
]
])
)
);
}
function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
function queryBabe (api: ApiInterfaceRx): Observable<[DeriveSessionIndexes, ResultSlotsFlat]> {
return api.derive.session.indexes().pipe(
switchMap((indexes): Observable<[DeriveSessionIndexes, ResultSlots]> =>
combineLatest([
of(indexes),
api.queryMulti<ResultSlots>([
api.query.babe.currentSlot,
api.query.babe.epochIndex,
api.query.babe.genesisSlot,
[api.query.staking.erasStartSessionIndex, indexes.activeEra]
])
])
),
map(([indexes, [currentSlot, epochIndex, genesisSlot, optStartIndex]]): [DeriveSessionIndexes, ResultSlotsFlat] => [
indexes, [currentSlot, epochIndex, genesisSlot, optStartIndex.unwrapOr(createType(api.registry, 'SessionIndex', 1))]
])
);
}
function queryBabeNoHistory (api: ApiInterfaceRx): Observable<[DeriveSessionIndexes, ResultSlotsFlat]> {
return combineLatest([
api.derive.session.indexes(),
api.queryMulti<ResultSlots>([
api.queryMulti<ResultSlotsFlat>([
api.query.babe.currentSlot,
api.query.babe.epochIndex,
api.query.babe.genesisSlot,
api.query.staking.currentEraStartSessionIndex
])
]).pipe(
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlots]): DerivedSessionInfo =>
createDerivedLatest(api, [
[true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra],
indexes,
slots
])
)
);
]);
}
/**
* @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras
* @description Retrieves all the session and era query and calculates specific values on it as the length of the session and eras
*/
export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo> {
const query = api.consts.babe
? infoLatestBabe // 2.x with Babe
: infoLatestAura; // 2.x with Aura (not all info there)
return memo((): Observable<DerivedSessionInfo> =>
query(api));
api.consts.babe
? (api.query.staking.erasStartSessionIndex
? queryBabe(api) // 2.x with Babe
: queryBabeNoHistory(api)
).pipe(
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlotsFlat]): DerivedSessionInfo =>
createDerived(api, [
[true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra],
indexes,
slots
])
)
)
: queryAura(api)
);
}
@@ -14,16 +14,17 @@ import { memo } from '../util';
export function electedInfo (api: ApiInterfaceRx): () => Observable<DerivedStakingElected> {
return memo((): Observable<DerivedStakingElected> =>
api.derive.staking.validators().pipe(
switchMap(({ currentElected }): Observable<[AccountId[], DerivedStakingQuery[]]> =>
switchMap(({ nextElected }): Observable<[AccountId[], DerivedStakingQuery[]]> =>
combineLatest([
of(currentElected),
combineLatest(currentElected.map((accountId): Observable<DerivedStakingQuery> =>
of(nextElected),
combineLatest(nextElected.map((accountId): Observable<DerivedStakingQuery> =>
api.derive.staking.query(accountId)
))
])
),
map(([currentElected, info]): DerivedStakingElected => ({
currentElected, info
map(([nextElected, info]): DerivedStakingElected => ({
info,
nextElected
}))
)
);
+24 -6
View File
@@ -2,15 +2,31 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { EraPoints } from '@polkadot/types/interfaces';
import { AccountId, EraIndex, EraPoints, EraRewardPoints, RewardPoint } from '@polkadot/types/interfaces';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedStakingOverview } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { createType } from '@polkadot/types';
import { memo } from '../util';
function retrievePointsPrev (api: ApiInterfaceRx, activeEra: EraIndex, currentElected: AccountId[]): Observable<EraRewardPoints> {
return api.query.staking.currentEraPointsEarned<EraPoints>(activeEra).pipe(
map(({ individual, total }): EraRewardPoints =>
createType(api.registry, 'EraRewardPoints', {
total,
individual: new Map<AccountId, RewardPoint>(
individual
.map((points): RewardPoint => createType(api.registry, 'RewardPoint', points))
.map((points, index): [AccountId, RewardPoint] => [currentElected[index], points])
)
})
)
);
}
/**
* @description Retrieve the staking overview, including elected and points earned
*/
@@ -20,14 +36,16 @@ export function overview (api: ApiInterfaceRx): () => Observable<DerivedStakingO
api.derive.session.indexes(),
api.derive.staking.validators()
]).pipe(
switchMap(([{ currentEra, currentIndex, validatorCount }, { currentElected, validators }]) =>
switchMap(([indexes, { nextElected, validators }]) =>
combineLatest([
of({ currentElected, currentEra, currentIndex, validators, validatorCount }),
api.query.staking.currentEraPointsEarned<EraPoints>(currentEra)
of({ ...indexes, nextElected, validators }),
api.query.staking.erasRewardPoints
? api.query.staking.erasRewardPoints<EraRewardPoints>(indexes.activeEra)
: retrievePointsPrev(api, indexes.activeEra, nextElected)
])
),
map(([{ currentElected, currentEra, currentIndex, validators, validatorCount }, eraPoints]): DerivedStakingOverview => ({
currentElected, currentEra, currentIndex, eraPoints, validators, validatorCount
map(([info, eraPoints]): DerivedStakingOverview => ({
...info, eraPoints
}))
));
}
+54 -33
View File
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, Exposure, Keys, Nominations, RewardDestination, StakingLedger, ValidatorPrefs } from '@polkadot/types/interfaces';
import { AccountId, Exposure, Keys, Nominations, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DerivedStakingQuery } from '../types';
@@ -13,7 +13,7 @@ import { createType, Option, Vec } from '@polkadot/types';
import { memo } from '../util';
type MultiResultV2 = [Option<AccountId>, Option<ITuple<[Nominations]>>, RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>, Option<StakingLedger>];
type MultiResult = [Option<AccountId>, Option<ITuple<[Nominations]>>, RewardDestination, ITuple<[ValidatorPrefs]>, Option<Keys>, Exposure];
function unwrapSessionIds (stashId: AccountId, queuedKeys: [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; sessionIds: AccountId[] } {
const sessionIds = (queuedKeys.find(([currentId]): boolean =>
@@ -27,20 +27,52 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: [AccountId, Keys][],
};
}
function retrieve (api: ApiInterfaceRx, stashId: AccountId): Observable<[Vec<ITuple<[AccountId, Keys]>>, MultiResultV2]> {
return combineLatest([
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
api.queryMulti([
[api.query.staking.bonded, stashId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
]) as Observable<MultiResultV2>
function retrievePrev (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResult> {
return api.queryMulti<MultiResult>([
[api.query.staking.bonded, stashId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]],
[api.query.staking.stakers, stashId]
]);
}
function retrieveCurr (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResult> {
return api.derive.session.indexes().pipe(
switchMap(({ activeEra }) =>
api.queryMulti<MultiResult>([
[api.query.staking.bonded, stashId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]],
[api.query.staking.erasStakers, [activeEra, stashId]]
])
)
);
}
function retrieveController (api: ApiInterfaceRx, stashId: AccountId, [queuedKeys, [controllerIdOpt, nominatorsOpt, rewardDestination, [validatorPrefs], nextKeys, exposure]]: [Vec<ITuple<[AccountId, Keys]>>, MultiResult]): Observable<DerivedStakingQuery> {
const controllerId = controllerIdOpt.unwrapOr(null);
return controllerId
? api.query.staking.ledger(controllerId).pipe(
map((stakingLedgerOpt): DerivedStakingQuery => ({
accountId: stashId,
controllerId,
exposure,
nominators: nominatorsOpt.unwrapOr([{ targets: [] }])[0].targets,
rewardDestination,
stakingLedger: stakingLedgerOpt.unwrapOr(undefined),
stashId,
validatorPrefs,
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
}))
)
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] });
}
/**
* @description From a stash, retrieve the controllerId and all relevant details
*/
@@ -48,26 +80,15 @@ export function query (api: ApiInterfaceRx): (accountId: Uint8Array | string) =>
return memo((accountId: Uint8Array | string): Observable<DerivedStakingQuery> => {
const stashId = createType(api.registry, 'AccountId', accountId);
return retrieve(api, stashId).pipe(
switchMap(([queuedKeys, [controllerIdOpt, nominatorsOpt, rewardDestination, stakers, [validatorPrefs], nextKeys]]): Observable<DerivedStakingQuery> => {
const controllerId = controllerIdOpt.unwrapOr(null);
return controllerId
? api.query.staking.ledger(controllerId).pipe(
map((stakingLedgerOpt): DerivedStakingQuery => ({
accountId: stashId,
controllerId,
nominators: nominatorsOpt.unwrapOr([{ targets: [] }])[0].targets,
rewardDestination,
stakers,
stakingLedger: stakingLedgerOpt.unwrapOr(undefined),
stashId,
validatorPrefs,
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
}))
)
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] });
})
return combineLatest([
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
api.query.staking.erasStakers
? retrieveCurr(api, stashId)
: retrievePrev(api, stashId)
]).pipe(
switchMap((result): Observable<DerivedStakingQuery> =>
retrieveController(api, stashId, result)
)
);
});
}
@@ -22,12 +22,16 @@ export function validators (api: ApiInterfaceRx): () => Observable<DeriveStaking
api.query.session
? api.query.session.validators()
: of([]),
api.query.staking
? api.query.staking.currentElected()
// FIXME need a replacement for currentElected in new
api.query.staking?.currentElected
? api.query.staking.erasStakers
? of(null)
: api.query.staking.currentElected()
: of([])
]).pipe(
map(([validators, currentElected]): DeriveStakingValidators => ({
currentElected, validators
map(([validators, nextElected]): DeriveStakingValidators => ({
nextElected: nextElected || validators,
validators
}))
));
}
+9 -7
View File
@@ -2,10 +2,10 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, AccountIndex, Balance, BalanceLock, BalanceLockTo212, BalanceOf, Bid, BidKind, BlockNumber, CollatorId, EraIndex, EraPoints, Exposure, Hash, Index, Keys, ParaId, ParaInfo, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, SocietyVote, StakingLedger, StrikeCount, TreasuryProposal, UpwardMessage, ValidatorPrefs, Vote, Votes, VoteIndex, VouchingStatus } from '@polkadot/types/interfaces';
import { AccountId, AccountIndex, Balance, BalanceLock, BalanceLockTo212, BalanceOf, Bid, BidKind, BlockNumber, CollatorId, EraIndex, EraRewardPoints, Exposure, Hash, Index, Keys, MomentOf, ParaId, ParaInfo, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, SocietyVote, StakingLedger, StrikeCount, TreasuryProposal, UpwardMessage, ValidatorPrefs, Vote, Votes, VoteIndex, VouchingStatus } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { Bytes, u32, Vec } from '@polkadot/types';
import { Bytes, Option, u32, Vec } from '@polkadot/types';
export type AccountIndexes = Record<string, AccountIndex>;
@@ -159,6 +159,8 @@ export interface DerivedReferendumVote {
}
export interface DeriveSessionIndexes {
activeEra: EraIndex;
activeEraStart: Option<MomentOf>;
currentEra: EraIndex;
currentIndex: SessionIndex;
validatorCount: u32;
@@ -200,22 +202,22 @@ export interface DeriveSocietyMember {
}
export interface DerivedStakingElected {
currentElected: AccountId[];
nextElected: AccountId[];
info: DerivedStakingQuery[];
}
export interface DeriveStakingValidators {
currentElected: AccountId[];
nextElected: AccountId[];
validators: AccountId[];
}
export interface DerivedStakingStash {
controllerId?: AccountId;
exposure?: Exposure;
nominators?: AccountId[];
nominateAt?: EraIndex;
rewardDestination?: RewardDestination;
nextKeys?: Keys;
stakers?: Exposure;
stashId?: AccountId;
validatorPrefs?: ValidatorPrefs;
}
@@ -233,8 +235,8 @@ export interface DerivedStakingAccount extends DerivedStakingQuery {
}
export interface DerivedStakingOverview extends DeriveSessionIndexes {
currentElected: AccountId[];
eraPoints: EraPoints;
eraPoints: EraRewardPoints;
nextElected: AccountId[];
validators: AccountId[];
}
+21 -8
View File
@@ -30,7 +30,7 @@ import { ApiId, BlockHash, ChainProperties, ExtrinsicOrHash, ExtrinsicStatus, He
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, ChangesTrieConfiguration, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, DispatchInfoTo190, Fixed64, H160, H256, H512, Hash, Header, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, LookupSource, LookupTarget, Moment, Origin, Perbill, Percent, Permill, Perquintill, Phantom, PhantomData, PreRuntime, Seal, SealV0, SignedBlock, StorageData, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { FullIdentification, IdentificationTuple, Keys, SessionIndex, SessionKeys1, SessionKeys2, SessionKeys3, SessionKeys4, SessionKeys5, SessionKeys6 } from '@polkadot/types/interfaces/session';
import { Bid, BidKind, BidKindVouch, SocietyJudgement, SocietyVote, StrikeCount, VouchingStatus } from '@polkadot/types/interfaces/society';
import { CompactAssignments, CompactScore, ElectionCompute, ElectionResult, ElectionStatus, EraIndex, EraPoints, EraRewards, Exposure, Forcing, IndividualExposure, KeyType, MomentOf, Nominations, PhragmenScore, Points, RewardDestination, SlashJournalEntry, SlashingSpans, SlashingSpansTo204, SpanIndex, SpanRecord, StakingLedger, UnappliedSlash, UnappliedSlashOther, UnlockChunk, ValidatorIndex, ValidatorPrefs, ValidatorPrefsTo145, ValidatorPrefsTo196 } from '@polkadot/types/interfaces/staking';
import { CompactAssignments, CompactScore, ElectionCompute, ElectionResult, ElectionStatus, EraIndex, EraPoints, EraRewardPoints, EraRewards, Exposure, Forcing, IndividualExposure, KeyType, MomentOf, Nominations, PhragmenScore, Points, RewardDestination, RewardPoint, SlashJournalEntry, SlashingSpans, SlashingSpansTo204, SpanIndex, SpanRecord, StakingLedger, StakingLedgerNew, StakingLedgerTo223, UnappliedSlash, UnappliedSlashOther, UnlockChunk, ValidatorIndex, ValidatorPrefs, ValidatorPrefsTo145, ValidatorPrefsTo196 } from '@polkadot/types/interfaces/staking';
import { AccountInfo, DigestOf, DispatchError, DispatchErrorModule, DispatchErrorTo198, DispatchResult, DispatchResultOf, DispatchResultTo198, Event, EventId, EventIndex, EventRecord, EventRecordTo76, Key, Phase, RefCount } from '@polkadot/types/interfaces/system';
import { OpenTip, OpenTipFinder, OpenTipTip, TreasuryProposal } from '@polkadot/types/interfaces/treasury';
import { Multiplier } from '@polkadot/types/interfaces/txpayment';
@@ -726,6 +726,13 @@ declare module '@polkadot/types/types/registry' {
VouchingStatus: VouchingStatus;
'Option<VouchingStatus>': Option<VouchingStatus>;
'Vec<VouchingStatus>': Vec<VouchingStatus>;
Points: Points;
'Compact<Points>': Compact<Points>;
'Option<Points>': Option<Points>;
'Vec<Points>': Vec<Points>;
EraPoints: EraPoints;
'Option<EraPoints>': Option<EraPoints>;
'Vec<EraPoints>': Vec<EraPoints>;
CompactAssignments: CompactAssignments;
'Option<CompactAssignments>': Option<CompactAssignments>;
'Vec<CompactAssignments>': Vec<CompactAssignments>;
@@ -745,9 +752,9 @@ declare module '@polkadot/types/types/registry' {
'Compact<EraIndex>': Compact<EraIndex>;
'Option<EraIndex>': Option<EraIndex>;
'Vec<EraIndex>': Vec<EraIndex>;
EraPoints: EraPoints;
'Option<EraPoints>': Option<EraPoints>;
'Vec<EraPoints>': Vec<EraPoints>;
EraRewardPoints: EraRewardPoints;
'Option<EraRewardPoints>': Option<EraRewardPoints>;
'Vec<EraRewardPoints>': Vec<EraRewardPoints>;
EraRewards: EraRewards;
'Option<EraRewards>': Option<EraRewards>;
'Vec<EraRewards>': Vec<EraRewards>;
@@ -772,13 +779,13 @@ declare module '@polkadot/types/types/registry' {
PhragmenScore: PhragmenScore;
'Option<PhragmenScore>': Option<PhragmenScore>;
'Vec<PhragmenScore>': Vec<PhragmenScore>;
Points: Points;
'Compact<Points>': Compact<Points>;
'Option<Points>': Option<Points>;
'Vec<Points>': Vec<Points>;
RewardDestination: RewardDestination;
'Option<RewardDestination>': Option<RewardDestination>;
'Vec<RewardDestination>': Vec<RewardDestination>;
RewardPoint: RewardPoint;
'Compact<RewardPoint>': Compact<RewardPoint>;
'Option<RewardPoint>': Option<RewardPoint>;
'Vec<RewardPoint>': Vec<RewardPoint>;
SlashJournalEntry: SlashJournalEntry;
'Option<SlashJournalEntry>': Option<SlashJournalEntry>;
'Vec<SlashJournalEntry>': Vec<SlashJournalEntry>;
@@ -795,6 +802,12 @@ declare module '@polkadot/types/types/registry' {
SpanRecord: SpanRecord;
'Option<SpanRecord>': Option<SpanRecord>;
'Vec<SpanRecord>': Vec<SpanRecord>;
StakingLedgerTo223: StakingLedgerTo223;
'Option<StakingLedgerTo223>': Option<StakingLedgerTo223>;
'Vec<StakingLedgerTo223>': Vec<StakingLedgerTo223>;
StakingLedgerNew: StakingLedgerNew;
'Option<StakingLedgerNew>': Option<StakingLedgerNew>;
'Vec<StakingLedgerNew>': Vec<StakingLedgerNew>;
StakingLedger: StakingLedger;
'Option<StakingLedger>': Option<StakingLedger>;
'Vec<StakingLedger>': Vec<StakingLedger>;
+71 -71
View File
@@ -12,92 +12,92 @@ import Compact from './Compact';
import Raw from './Raw';
import { compareMap, decodeU8a, typeToConstructor } from './utils';
/** @internal */
function decodeBTreeMapFromU8a<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, u8a: Uint8Array): Map<K, V> {
const output = new Map<K, V>();
const [offset, length] = Compact.decodeU8a(u8a);
const types = [];
for (let i = 0; i < length.toNumber(); i++) {
types.push(KeyClass, ValClass);
}
const values = decodeU8a(registry, u8a.subarray(offset), types);
for (let i = 0; i < values.length; i += 2) {
output.set(values[i] as K, values[i + 1] as V);
}
return output;
}
/** @internal */
function decodeBTreeMapFromMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Map<any, any>): Map<K, V> {
const output = new Map<K, V>();
value.forEach((v: any, k: any) => {
let key, val;
try {
key = (k instanceof KeyClass) ? k : new KeyClass(registry, k);
val = (v instanceof ValClass) ? v : new ValClass(registry, v);
} catch (error) {
console.error('Failed to decode BTreeMap key or value:', error.message);
throw error;
}
output.set(key, val);
});
return output;
}
/**
* Decode input to pass into constructor.
*
* @param KeyClass - Type of the map key
* @param ValClass - Type of the map value
* @param value - Value to decode, one of:
* - null
* - undefined
* - hex
* - Uint8Array
* - Map<any, any>, where both key and value types are either
* constructors or decodeable values for their types.
* @param jsonMap
* @internal
*/
function decodeBTreeMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Uint8Array | string | Map<any, any>): Map<K, V> {
if (!value) {
return new Map<K, V>();
} else if (isHex(value)) {
return decodeBTreeMap(registry, KeyClass, ValClass, hexToU8a(value));
} else if (isU8a(value)) {
return decodeBTreeMapFromU8a<K, V>(registry, KeyClass, ValClass, u8aToU8a(value));
} else if (value instanceof Map) {
return decodeBTreeMapFromMap<K, V>(registry, KeyClass, ValClass, value);
}
throw new Error('BTreeMap: cannot decode type');
}
export default class BTreeMap<K extends Codec = Codec, V extends Codec = Codec> extends Map<K, V> implements Codec {
public readonly registry: Registry;
private readonly _KeyClass: Constructor<K>;
protected _KeyClass: Constructor<K>;
private readonly _ValClass: Constructor<V>;
protected _ValClass: Constructor<V>;
constructor (registry: Registry, keyType: Constructor<K> | keyof InterfaceTypes, valType: Constructor<V> | keyof InterfaceTypes, rawValue: any) {
const KeyClass = typeToConstructor(registry, keyType);
const ValClass = typeToConstructor(registry, valType);
super(BTreeMap.decodeBTreeMap(registry, KeyClass, ValClass, rawValue));
super(decodeBTreeMap(registry, KeyClass, ValClass, rawValue));
this.registry = registry;
this._KeyClass = KeyClass;
this._ValClass = ValClass;
}
/**
* Decode input to pass into constructor.
*
* @param KeyClass - Type of the map key
* @param ValClass - Type of the map value
* @param value - Value to decode, one of:
* - null
* - undefined
* - hex
* - Uint8Array
* - Map<any, any>, where both key and value types are either
* constructors or decodeable values for their types.
* @param jsonMap
* @internal
*/
private static decodeBTreeMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Uint8Array | string | Map<any, any>): Map<K, V> {
if (!value) {
return new Map<K, V>();
} else if (isHex(value)) {
return BTreeMap.decodeBTreeMap(registry, KeyClass, ValClass, hexToU8a(value));
} else if (isU8a(value)) {
return BTreeMap.decodeBTreeMapFromU8a<K, V>(registry, KeyClass, ValClass, u8aToU8a(value));
} else if (value instanceof Map) {
return BTreeMap.decodeBTreeMapFromMap<K, V>(registry, KeyClass, ValClass, value);
}
throw new Error('BTreeMap: cannot decode type');
}
/** @internal */
private static decodeBTreeMapFromU8a<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, u8a: Uint8Array): Map<K, V> {
const output = new Map<K, V>();
const [offset, length] = Compact.decodeU8a(u8a);
const types = [];
for (let i = 0; i < length.toNumber(); i++) {
types.push(KeyClass, ValClass);
}
const values = decodeU8a(registry, u8a.subarray(offset), types);
for (let i = 0; i < values.length; i += 2) {
output.set(values[i] as K, values[i + 1] as V);
}
return output;
}
/** @internal */
private static decodeBTreeMapFromMap<K extends Codec = Codec, V extends Codec = Codec> (registry: Registry, KeyClass: Constructor<K>, ValClass: Constructor<V>, value: Map<any, any>): Map<K, V> {
const output = new Map<K, V>();
value.forEach((v: any, k: any) => {
let key, val;
try {
key = (k instanceof KeyClass) ? k : new KeyClass(registry, k);
val = (v instanceof ValClass) ? v : new ValClass(registry, v);
} catch (error) {
console.error('Failed to decode BTreeMap key or value:', error.message);
throw error;
}
output.set(key, val);
});
return output;
}
public static with<K extends Codec, V extends Codec> (keyType: Constructor<K> | keyof InterfaceTypes, valType: Constructor<V> | keyof InterfaceTypes): Constructor<BTreeMap<K, V>> {
return class extends BTreeMap<K, V> {
constructor (registry: Registry, value?: any) {
@@ -2,8 +2,17 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
const deprecated = {
Points: 'u32',
EraPoints: {
total: 'Points',
individual: 'Vec<Points>'
}
};
export default {
types: {
...deprecated,
CompactAssignments: {
votes1: 'Vec<(AccountId, [CompactScore; 0], AccountId)>',
votes2: 'Vec<(AccountId, [CompactScore; 1], AccountId)>',
@@ -39,9 +48,9 @@ export default {
}
},
EraIndex: 'u32',
EraPoints: {
total: 'Points',
individual: 'Vec<Points>'
EraRewardPoints: {
total: 'RewardPoint',
individual: 'BTreeMap<AccountId, RewardPoint>'
},
EraRewards: {
total: 'u32',
@@ -80,6 +89,7 @@ export default {
'Controller'
]
},
RewardPoint: 'u32',
SlashJournalEntry: {
who: 'AccountId',
amount: 'Balance',
@@ -101,12 +111,21 @@ export default {
slashed: 'Balance',
paidOut: 'Balance'
},
StakingLedger: {
StakingLedgerTo223: {
stash: 'AccountId',
total: 'Compact<Balance>',
active: 'Compact<Balance>',
unlocking: 'Vec<UnlockChunk>'
},
// TODO Enable as default when new staking payouts go live
StakingLedgerNew: {
stash: 'AccountId',
total: 'Compact<Balance>',
active: 'Compact<Balance>',
unlocking: 'Vec<UnlockChunk>',
nextReward: 'EraIndex'
},
StakingLedger: 'StakingLedgerTo223',
UnappliedSlashOther: '(AccountId, Balance)',
UnappliedSlash: {
validator: 'AccountId',
+23 -2
View File
@@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
import { ITuple } from '@polkadot/types/types';
import { Compact, Enum, Struct, Vec } from '@polkadot/types/codec';
import { BTreeMap, Compact, Enum, Struct, Vec } from '@polkadot/types/codec';
import { bool, u128, u16, u32 } from '@polkadot/types/primitive';
import { AccountId, Balance, BlockNumber, Moment, Perbill } from '@polkadot/types/interfaces/runtime';
@@ -60,6 +60,12 @@ export interface EraPoints extends Struct {
readonly individual: Vec<Points>;
}
/** @name EraRewardPoints */
export interface EraRewardPoints extends Struct {
readonly total: RewardPoint;
readonly individual: BTreeMap<AccountId, RewardPoint>;
}
/** @name EraRewards */
export interface EraRewards extends Struct {
readonly total: u32;
@@ -113,6 +119,9 @@ export interface RewardDestination extends Enum {
readonly isController: boolean;
}
/** @name RewardPoint */
export interface RewardPoint extends u32 {}
/** @name SlashingSpans */
export interface SlashingSpans extends Struct {
readonly spanIndex: SpanIndex;
@@ -145,7 +154,19 @@ export interface SpanRecord extends Struct {
}
/** @name StakingLedger */
export interface StakingLedger extends Struct {
export interface StakingLedger extends StakingLedgerTo223 {}
/** @name StakingLedgerNew */
export interface StakingLedgerNew extends Struct {
readonly stash: AccountId;
readonly total: Compact<Balance>;
readonly active: Compact<Balance>;
readonly unlocking: Vec<UnlockChunk>;
readonly nextReward: EraIndex;
}
/** @name StakingLedgerTo223 */
export interface StakingLedgerTo223 extends Struct {
readonly stash: AccountId;
readonly total: Compact<Balance>;
readonly active: Compact<Balance>;
+14 -7
View File
@@ -43,7 +43,8 @@ const TYPES_POLKADOT_VERSIONED: OverrideVersionedType[] = [
types: {
Address: 'GenericAddress',
BalanceLock: 'BalanceLockTo212',
Keys: 'SessionKeys5'
Keys: 'SessionKeys5',
StakingLedger: 'StakingLedgerTo223'
}
},
{
@@ -51,7 +52,8 @@ const TYPES_POLKADOT_VERSIONED: OverrideVersionedType[] = [
types: {
// Indices optional, not in transaction
Address: 'AccountId',
Keys: 'SessionKeys5'
Keys: 'SessionKeys5',
StakingLedger: 'StakingLedgerTo223'
}
}
];
@@ -64,7 +66,8 @@ const TYPES_KUSAMA_VERSIONED: OverrideVersionedType[] = [
BalanceLock: 'BalanceLockTo212',
DispatchError: 'DispatchErrorTo198',
Keys: 'SessionKeys5',
SlashingSpans: 'SlashingSpansTo204'
SlashingSpans: 'SlashingSpansTo204',
StakingLedger: 'StakingLedgerTo223'
}
},
{
@@ -73,7 +76,8 @@ const TYPES_KUSAMA_VERSIONED: OverrideVersionedType[] = [
Address: 'GenericAddress',
BalanceLock: 'BalanceLockTo212',
Keys: 'SessionKeys5',
SlashingSpans: 'SlashingSpansTo204'
SlashingSpans: 'SlashingSpansTo204',
StakingLedger: 'StakingLedgerTo223'
}
},
{
@@ -81,7 +85,8 @@ const TYPES_KUSAMA_VERSIONED: OverrideVersionedType[] = [
types: {
Address: 'GenericAddress',
BalanceLock: 'BalanceLockTo212',
Keys: 'SessionKeys5'
Keys: 'SessionKeys5',
StakingLedger: 'StakingLedgerTo223'
}
},
{
@@ -89,7 +94,8 @@ const TYPES_KUSAMA_VERSIONED: OverrideVersionedType[] = [
types: {
// Indices optional, not in transaction
Address: 'AccountId',
Keys: 'SessionKeys5'
Keys: 'SessionKeys5',
StakingLedger: 'StakingLedgerTo223'
}
}
];
@@ -110,7 +116,8 @@ const TYPES_META: OverrideVersionedType[] = [
BlockNumber: 'u64',
Index: 'u64',
EventRecord: 'EventRecordTo76',
ValidatorPrefs: 'ValidatorPrefsTo145'
ValidatorPrefs: 'ValidatorPrefsTo145',
StakingLedger: 'StakingLedgerTo223'
}
}
];