diff --git a/packages/api-derive/src/session/info.ts b/packages/api-derive/src/session/info.ts index f2a4a2779c1c..0358a6a08b35 100644 --- a/packages/api-derive/src/session/info.ts +++ b/packages/api-derive/src/session/info.ts @@ -51,7 +51,7 @@ function createDerivedV1 ([bestNumber, { currentIndex, validatorCount }, [_lastL function createDerivedLatest ([[hasBabe, epochDuration, sessionsPerEra], { currentIndex, currentEra, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, currentEraStartSessionIndex]]: Result): DerivedSessionInfo { const epochStartSlot = epochIndex.mul(epochDuration).add(epochOrGenesisStartSlot); const sessionProgress = currentSlot.sub(epochStartSlot); - const eraProgress = currentIndex.sub(currentEraStartSessionIndex).add(sessionProgress); + const eraProgress = currentIndex.sub(currentEraStartSessionIndex).mul(epochDuration).add(sessionProgress); return { currentEra, diff --git a/packages/api-derive/src/staking/info.ts b/packages/api-derive/src/staking/info.ts index 1b3627bb2a60..09db87e093d1 100644 --- a/packages/api-derive/src/staking/info.ts +++ b/packages/api-derive/src/staking/info.ts @@ -3,7 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { ApiInterfaceRx } from '@polkadot/api/types'; -import { AccountId, Balance, BlockNumber, Exposure, Keys, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces'; +import { AccountId, Balance, BlockNumber, Exposure, Keys, Nominations, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces'; import { ITuple } from '@polkadot/types/types'; import { DerivedRecentlyOffline, DerivedSessionInfo, DerivedStaking, DerivedUnlocking } from '../types'; @@ -152,62 +152,60 @@ function retrieveInfoV1 (api: ApiInterfaceRx, accountId: AccountId, stashId: Acc [api.query.staking.stakers, stashId], [api.query.staking.validators, stashId] ]) as Observable - ]).pipe(map(([ - sessionInfo, recentlyOffline, - [nextKeyFor, stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]] - ]: [DerivedSessionInfo, DerivedRecentlyOffline, MultiResultV1]): DerivedStaking => + ]).pipe(map(([sessionInfo, recentlyOffline, [nextKeyFor, stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]]: [DerivedSessionInfo, DerivedRecentlyOffline, MultiResultV1]): DerivedStaking => parseResult({ accountId, controllerId, stashId, sessionInfo, recentlyOffline, nextKeyFor, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs }) )); } -type MultiResultV2 = [Option, [Vec], RewardDestination, Exposure, [ValidatorPrefs], Option]; +type MultiResultV2 = [[Vec] | Option>, RewardDestination, Exposure, [ValidatorPrefs], Option, Option]; function retrieveInfoV2 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable { return combineLatest([ api.derive.session.info(), api.query.session.queuedKeys>>(), api.queryMulti([ - [api.query.staking.ledger, controllerId], [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]] + [api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]], + [api.query.staking.ledger, controllerId] ]) as Observable - ]).pipe(map(([ - sessionInfo, queuedKeys, - [stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs], nextKeys] - ]: [DerivedSessionInfo, [AccountId, Keys][], MultiResultV2]): DerivedStaking => - parseResult({ + ]).pipe(map(([sessionInfo, queuedKeys, [_nominators, rewardDestination, stakers, [validatorPrefs], nextKeys, stakingLedger]]: [DerivedSessionInfo, [AccountId, Keys][], MultiResultV2]): DerivedStaking => { + // if we have staking.storageVersion it indicates the new structure, unwrap as needed + // FIXME We really want to be pulling all the new (valuable) info along + const nominators: AccountId[] = api.query.staking.storageVersion + ? (_nominators as Option>).isSome + ? (_nominators as Option>).unwrap()[0].targets + : [] + : (_nominators as [Vec])[0]; + + return parseResult({ accountId, controllerId, stashId, sessionInfo, queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys - }) - )); + }); + })); } function retrieveV1 (api: ApiInterfaceRx, controllerId: AccountId): Observable { return api.query.staking .ledger>(controllerId) - .pipe( - switchMap((stakingLedger): Observable => - stakingLedger.isSome - ? retrieveInfoV1(api, controllerId, stakingLedger.unwrap().stash, controllerId) - : of({ accountId: controllerId, nextSessionIds: [], sessionIds: [] }) - ) - ); + .pipe(switchMap((stakingLedger): Observable => + stakingLedger.isSome + ? retrieveInfoV1(api, controllerId, stakingLedger.unwrap().stash, controllerId) + : of({ accountId: controllerId, nextSessionIds: [], sessionIds: [] }) + )); } function retrieveV2 (api: ApiInterfaceRx, stashId: AccountId): Observable { return api.query.staking .bonded>(stashId) - .pipe( - switchMap((controllerId): Observable => - controllerId.isSome - ? retrieveInfoV2(api, stashId, stashId, controllerId.unwrap()) - : of({ accountId: stashId, nextSessionIds: [], sessionIds: [] }) - ) - ); + .pipe(switchMap((controllerId): Observable => + controllerId.isSome + ? retrieveInfoV2(api, stashId, stashId, controllerId.unwrap()) + : of({ accountId: stashId, nextSessionIds: [], sessionIds: [] }) + )); } /** diff --git a/packages/types/src/codec/create/sanitize.ts b/packages/types/src/codec/create/sanitize.ts index 888f06846f94..0f3aafa16da2 100644 --- a/packages/types/src/codec/create/sanitize.ts +++ b/packages/types/src/codec/create/sanitize.ts @@ -36,10 +36,12 @@ const mappings: Mapper[] = [ _alias('Lookup::Source', 'Address'), // alias Lookup::Target to AccountId (always the case) _alias('Lookup::Target', 'AccountId'), - // alias for grandpa, as used in polkadot - _alias('grandpa::AuthorityId', 'AuthorityId'), - // specific for SessionIndex (could make this session::, but be conservative) - _alias('session::SessionIndex', 'SessionIndex'), + // alias for grandpa internal, as used in polkadot + _alias('grandpa::', ''), + // specific for session internal + _alias('session::', ''), + // specific for staking/slashing.rs internal + _alias('slashing::', ''), // HACK duplication between contracts & primitives, however contracts prefixed with exec _alias('exec::StorageKey', 'ContractStorageKey'), // Phantom diff --git a/packages/types/src/interfaceRegistry.ts b/packages/types/src/interfaceRegistry.ts index a585843a5124..39a6bdc4f591 100644 --- a/packages/types/src/interfaceRegistry.ts +++ b/packages/types/src/interfaceRegistry.ts @@ -19,7 +19,7 @@ import { AuthorityIndex, AuthorityList, AuthorityWeight, NextAuthority, PendingP import { AuthIndex, AuthoritySignature, Heartbeat, OpaqueMultiaddr, OpaqueNetworkState, OpaquePeerId } from '@polkadot/types/interfaces/imOnline'; import { Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences'; import { FullIdentification, IdentificationTuple, Keys, SessionIndex, SessionKeys3, SessionKeys4, SessionKeys5, SessionKeysPolkadot, SessionKeysSubstrate } from '@polkadot/types/interfaces/session'; -import { EraIndex, EraPoints, EraRewards, Exposure, Forcing, IndividualExposure, MomentOf, Points, RewardDestination, SlashJournalEntry, StakingLedger, UnlockChunk, ValidatorPrefs, ValidatorPrefs0to145 } from '@polkadot/types/interfaces/staking'; +import { EraIndex, EraPoints, EraRewards, Exposure, Forcing, IndividualExposure, MomentOf, Nominations, Points, RewardDestination, SlashJournalEntry, SlashingSpans, SpanIndex, SpanRecord, StakingLedger, UnappliedSlash, UnappliedSlashOther, UnlockChunk, ValidatorPrefs, ValidatorPrefs0to145 } from '@polkadot/types/interfaces/staking'; import { DigestOf, DispatchError, Event, EventId, EventIndex, EventRecord, EventRecord0to76, Key, Phase } from '@polkadot/types/interfaces/system'; import { TreasuryProposal } from '@polkadot/types/interfaces/treasury'; import { Multiplier } from '@polkadot/types/interfaces/txpayment'; @@ -618,6 +618,9 @@ export interface InterfaceRegistry { MomentOf: MomentOf; 'Option': Option; 'Vec': Vec; + Nominations: Nominations; + 'Option': Option; + 'Vec': Vec; Points: Points; 'Compact': Compact; 'Option': Option; @@ -628,9 +631,25 @@ export interface InterfaceRegistry { SlashJournalEntry: SlashJournalEntry; 'Option': Option; 'Vec': Vec; + SlashingSpans: SlashingSpans; + 'Option': Option; + 'Vec': Vec; + SpanIndex: SpanIndex; + 'Compact': Compact; + 'Option': Option; + 'Vec': Vec; + SpanRecord: SpanRecord; + 'Option': Option; + 'Vec': Vec; StakingLedger: StakingLedger; 'Option': Option; 'Vec': Vec; + UnappliedSlashOther: UnappliedSlashOther; + 'Option': Option; + 'Vec': Vec; + UnappliedSlash: UnappliedSlash; + 'Option': Option; + 'Vec': Vec; UnlockChunk: UnlockChunk; 'Option': Option; 'Vec': Vec; diff --git a/packages/types/src/interfaces/staking/definitions.ts b/packages/types/src/interfaces/staking/definitions.ts index 4c1ae157d44f..9de1f2a3b49c 100644 --- a/packages/types/src/interfaces/staking/definitions.ts +++ b/packages/types/src/interfaces/staking/definitions.ts @@ -31,6 +31,11 @@ export default { value: 'Compact' }, MomentOf: 'Moment', + Nominations: { + targets: 'Vec', + submittedIn: 'EraIndex', + suppressed: 'bool' + }, Points: 'u32', RewardDestination: { _enum: [ @@ -44,12 +49,30 @@ export default { amount: 'Balance', ownSlash: 'Balance' }, + SlashingSpans: { + spanIndex: 'SpanIndex', + lastStart: 'EraIndex', + prior: 'Vec' + }, + SpanIndex: 'u32', + SpanRecord: { + slashed: 'Balance', + paidOut: 'Balance' + }, StakingLedger: { stash: 'AccountId', total: 'Compact', active: 'Compact', unlocking: 'Vec' }, + UnappliedSlashOther: '(AccountId, Balance)', + UnappliedSlash: { + validator: 'AccountId', + own: 'Balance', + others: 'Vec', + reporters: 'Vec', + payout: 'Balance' + }, UnlockChunk: { value: 'Compact', era: 'Compact' diff --git a/packages/types/src/interfaces/staking/types.ts b/packages/types/src/interfaces/staking/types.ts index 5d2417410fc4..7220118c40c5 100644 --- a/packages/types/src/interfaces/staking/types.ts +++ b/packages/types/src/interfaces/staking/types.ts @@ -1,8 +1,9 @@ // Auto-generated via `yarn build:interfaces`, do not edit /* eslint-disable @typescript-eslint/no-empty-interface */ +import { ITuple } from '@polkadot/types/types'; import { Compact, Enum, Struct, Vec } from '@polkadot/types/codec'; -import { u32 } from '@polkadot/types/primitive'; +import { bool, u32 } from '@polkadot/types/primitive'; import { AccountId, Balance, BlockNumber, Moment } from '@polkadot/types/interfaces/runtime'; /** u32 */ @@ -57,6 +58,16 @@ export interface IndividualExposure extends Struct { /** Moment */ export interface MomentOf extends Moment {} +/** Struct */ +export interface Nominations extends Struct { + /** Vec */ + readonly targets: Vec; + /** EraIndex */ + readonly submittedIn: EraIndex; + /** bool */ + readonly suppressed: bool; +} + /** u32 */ export interface Points extends u32 {} @@ -70,6 +81,16 @@ export interface RewardDestination extends Enum { readonly isController: boolean; } +/** Struct */ +export interface SlashingSpans extends Struct { + /** SpanIndex */ + readonly spanIndex: SpanIndex; + /** EraIndex */ + readonly lastStart: EraIndex; + /** Vec */ + readonly prior: Vec; +} + /** Struct */ export interface SlashJournalEntry extends Struct { /** AccountId */ @@ -80,6 +101,17 @@ export interface SlashJournalEntry extends Struct { readonly ownSlash: Balance; } +/** u32 */ +export interface SpanIndex extends u32 {} + +/** Struct */ +export interface SpanRecord extends Struct { + /** Balance */ + readonly slashed: Balance; + /** Balance */ + readonly paidOut: Balance; +} + /** Struct */ export interface StakingLedger extends Struct { /** AccountId */ @@ -92,6 +124,23 @@ export interface StakingLedger extends Struct { readonly unlocking: Vec; } +/** Struct */ +export interface UnappliedSlash extends Struct { + /** AccountId */ + readonly validator: AccountId; + /** Balance */ + readonly own: Balance; + /** Vec */ + readonly others: Vec; + /** Vec */ + readonly reporters: Vec; + /** Balance */ + readonly payout: Balance; +} + +/** ITuple<[AccountId, Balance]> */ +export interface UnappliedSlashOther extends ITuple<[AccountId, Balance]> {} + /** Struct */ export interface UnlockChunk extends Struct { /** Compact */