Add api.derive.democracy.dispatchQueue (#2107)

This commit is contained in:
Jaco Greeff
2020-03-27 17:59:22 +01:00
committed by GitHub
parent 88519eff3f
commit 0d067c9484
7 changed files with 130 additions and 83 deletions
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { ReferendumInfo, ReferendumInfoTo239, ReferendumStatus } from '@polkadot/types/interfaces';
import { ReferendumInfo, ReferendumInfoTo239 } from '@polkadot/types/interfaces';
import { DeriveReferendum } from '../types';
import BN from 'bn.js';
@@ -12,39 +12,20 @@ import { map } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { memo } from '../util';
import { PreImage } from './proposals';
import { getStatus } from './util';
import { getStatus, parseImage } from './util';
function constructInfo (api: ApiInterfaceRx, index: BN | number, status: ReferendumStatus | ReferendumInfoTo239, _preimage?: PreImage): DeriveReferendum | null {
const preImage = _preimage?.isSome
? _preimage.unwrap()
: null;
return {
index: api.registry.createType('PropIndex', index),
hash: status.proposalHash,
proposal: preImage
? api.registry.createType('Proposal', preImage[0].toU8a(true))
: undefined,
preimage: preImage
? {
at: preImage[3],
balance: preImage[2],
proposer: preImage[1]
}
: undefined,
status
};
}
export function _referendumInfo (api: ApiInterfaceRx): (id: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>) => Observable<DeriveReferendum | null> {
return memo((id: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>): Observable<DeriveReferendum | null> => {
export function _referendumInfo (api: ApiInterfaceRx): (index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>) => Observable<DeriveReferendum | null> {
return memo((index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>): Observable<DeriveReferendum | null> => {
const status = getStatus(info);
return status
? api.query.democracy.preimages(status.proposalHash).pipe(
map((preimage?: PreImage): DeriveReferendum | null =>
constructInfo(api, id, status, preimage)
)
map((preimage): DeriveReferendum => ({
index: api.registry.createType('ReferendumIndex', index),
image: parseImage(api, preimage),
imageHash: status.proposalHash,
status
}))
)
: of(null);
});
@@ -0,0 +1,38 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BlockNumber, Hash, ReferendumIndex } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveDispatch } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Vec } from '@polkadot/types';
import { memo } from '../util';
export function dispatchQueue (api: ApiInterfaceRx): () => Observable<DeriveDispatch[]> {
return memo((): Observable<DeriveDispatch[]> =>
api.query.democracy?.dispatchQueue
? api.query.democracy.dispatchQueue<Vec<ITuple<[BlockNumber, Hash, ReferendumIndex]>>>().pipe(
switchMap((dispatches) =>
combineLatest([
of(dispatches),
api.derive.democracy.preimages(
dispatches.map(([, hash]) => hash))
])
),
map(([dispatches, images]) =>
dispatches.map(([at, imageHash, index], dispatchIndex): DeriveDispatch => ({
at,
index,
image: images[dispatchIndex],
imageHash
}))
)
)
: of([])
);
}
@@ -5,6 +5,8 @@
export * from './_referendumsVotes';
export * from './_referendumVotes';
export * from './_referendumInfo';
export * from './dispatchQueue';
export * from './preimages';
export * from './proposals';
export * from './referendums';
export * from './referendumsActive';
@@ -0,0 +1,29 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveProposalImage } from '../types';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Bytes, Option } from '@polkadot/types';
import { memo } from '../util';
import { parseImage } from './util';
type PreImage = Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>;
export function preimages (api: ApiInterfaceRx): (hashes: Hash[]) => Observable<(DeriveProposalImage | undefined)[]> {
return memo((hashes: Hash[]): Observable<(DeriveProposalImage | undefined)[]> =>
api.query.democracy.preimages.multi<PreImage>(hashes).pipe(
map((images): (DeriveProposalImage | undefined)[] =>
images.map((imageOpt) =>
parseImage(api, imageOpt)
)
)
)
);
}
+14 -42
View File
@@ -2,61 +2,35 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash, PropIndex, Proposal } from '@polkadot/types/interfaces';
import { AccountId, Balance, Hash, PropIndex } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveProposal } from '../types';
import { DeriveProposalImage, DeriveProposal } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Bytes, Option, Vec } from '@polkadot/types';
import { Option, Vec } from '@polkadot/types';
import { memo } from '../util';
export type PreImage = Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>;
type Depositors = Option<ITuple<[Balance, Vec<AccountId>]>>;
type Proposals = Vec<ITuple<[PropIndex, Hash, AccountId]>>;
interface Result {
depositors: Depositors[];
preimages: PreImage[];
proposals: Proposals;
}
function parse (api: ApiInterfaceRx, { depositors, proposals, preimages }: Result): DeriveProposal[] {
function parse ([proposals, images, depositors]: [Proposals, (DeriveProposalImage | undefined)[], Depositors[]]): DeriveProposal[] {
return proposals
.filter(([, , proposer], index): boolean =>
!!(depositors[index]?.isSome) && !proposer.isEmpty
)
.map(([propIndex, hash, proposer], index): DeriveProposal => {
const preimage = preimages[index].unwrapOr(null);
const depositor = depositors[index].unwrap();
let proposal: undefined | Proposal;
// we could end up in a situation where the proposal is non-decodable, e.g. after an upgrade
if (preimage) {
try {
proposal = api.registry.createType('Proposal', preimage[0].toU8a(true));
} catch (error) {
console.error(error);
}
}
.map(([index, imageHash, proposer], proposalIndex): DeriveProposal => {
const [balance, seconds] = depositors[proposalIndex].unwrap();
return {
balance: depositor[0],
hash,
index: propIndex,
preimage: preimage
? {
at: preimage[3],
balance: preimage[2],
proposer: preimage[1]
}
: undefined,
proposal,
balance,
index,
image: images[proposalIndex],
imageHash,
proposer,
seconds: depositor[1]
seconds
};
});
}
@@ -68,16 +42,14 @@ export function proposals (api: ApiInterfaceRx): () => Observable<DeriveProposal
switchMap((proposals) =>
combineLatest([
of(proposals),
api.query.democracy.preimages.multi<PreImage>(
api.derive.democracy.preimages(
proposals.map(([, hash]): Hash => hash)),
api.query.democracy.depositOf.multi<Depositors>(
proposals.map(([index]): PropIndex => index))
])
),
map(([proposals, preimages, depositors]): DeriveProposal[] =>
parse(api, { depositors, proposals, preimages })
)
map(parse)
)
: of([] as DeriveProposal[])
: of([])
);
}
+15 -9
View File
@@ -2,32 +2,38 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash, Proposal, PropIndex, ReferendumInfoTo239, ReferendumStatus, Vote } from '@polkadot/types/interfaces';
import { AccountId, Balance, BlockNumber, Hash, Proposal, PropIndex, ReferendumInfoTo239, ReferendumStatus, Vote, ReferendumIndex } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { Vec } from '@polkadot/types';
export interface DeriveProposalPreImage {
export interface DeriveDispatch {
at: BlockNumber;
index: ReferendumIndex;
imageHash: Hash;
image?: DeriveProposalImage;
}
export interface DeriveProposalImage {
at: BlockNumber;
balance: Balance;
proposal?: Proposal;
proposer: AccountId;
}
export interface DeriveProposal {
balance?: Balance;
hash: Hash;
index: PropIndex;
preimage?: DeriveProposalPreImage;
proposal?: Proposal;
image?: DeriveProposalImage;
imageHash: Hash;
proposer: AccountId;
seconds: Vec<AccountId>;
}
export interface DeriveReferendum {
hash: Hash;
index: PropIndex;
preimage?: DeriveProposalPreImage;
proposal?: Proposal;
index: ReferendumIndex;
image?: DeriveProposalImage;
imageHash: Hash;
status: ReferendumStatus | ReferendumInfoTo239;
}
+22 -3
View File
@@ -2,11 +2,13 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ReferendumInfo, ReferendumInfoTo239, ReferendumStatus, Tally, VoteThreshold } from '@polkadot/types/interfaces';
import { DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes, DeriveReferendumVoteState } from '../types';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, Balance, BlockNumber, Proposal, ReferendumInfo, ReferendumInfoTo239, ReferendumStatus, Tally, VoteThreshold } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveProposalImage, DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes, DeriveReferendumVoteState } from '../types';
import BN from 'bn.js';
import { Option } from '@polkadot/types';
import { Bytes, Option } from '@polkadot/types';
import { bnSqrt } from '@polkadot/util';
function isOldInfo (info: ReferendumInfo | ReferendumInfoTo239): info is ReferendumInfoTo239 {
@@ -142,3 +144,20 @@ export function getStatus (info: Option<ReferendumInfo | ReferendumInfoTo239>):
// done, we don't include it here... only currently active
return null;
}
export function parseImage (api: ApiInterfaceRx, imageOpt: Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>): DeriveProposalImage | undefined {
if (imageOpt.isNone) {
return;
}
let proposal: Proposal | undefined;
const [bytes, proposer, balance, at] = imageOpt.unwrap();
try {
proposal = api.registry.createType('Proposal', bytes.toU8a(true));
} catch (error) {
console.error(error);
}
return { at, balance, proposal, proposer };
}