From 77bf33b4e45f650da4789efe689c81707eec9e35 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 9 Dec 2019 18:17:41 +0100 Subject: [PATCH] Derive with optional democracy (#1657) * Derive with optional democracy * Cleanup optionals * Multi for preimage retrievals * Convert indexes to hex before lookup --- .../api-derive/src/democracy/proposals.ts | 104 +++++++++--------- .../api-derive/src/democracy/referendums.ts | 27 +++-- packages/types/src/codec/create/registry.ts | 13 ++- 3 files changed, 75 insertions(+), 69 deletions(-) diff --git a/packages/api-derive/src/democracy/proposals.ts b/packages/api-derive/src/democracy/proposals.ts index 26da5e91e7..0dfed18acc 100644 --- a/packages/api-derive/src/democracy/proposals.ts +++ b/packages/api-derive/src/democracy/proposals.ts @@ -14,62 +14,62 @@ import { Bytes, Option, Vec, createType } from '@polkadot/types'; import { memo } from '../util'; export type PreImage = Option>; + type Depositors = Option]>>; +type Proposals = Vec>; + +interface Result { + depositors: Depositors[]; + preimages: PreImage[]; + proposals: Proposals; +} + +function parse (api: ApiInterfaceRx, { depositors, proposals, preimages }: Result): DeriveProposal[] { + return proposals + .filter(([, , proposer], index): boolean => + !!(preimages[index]?.isSome) && !!(depositors[index]?.isSome) && !proposer.isEmpty + ) + .map(([propIndex, hash, proposer], index): DeriveProposal => { + const preimage = preimages[index].unwrapOr(null); + const depositor = depositors[index].unwrap(); + + return { + balance: depositor[0], + hash, + index: propIndex, + preimage: preimage + ? { + at: preimage[3], + balance: preimage[2], + proposer: preimage[1] + } + : undefined, + proposal: preimage + ? createType(api.registry, 'Proposal', preimage[0].toU8a(true)) + : undefined, + proposer, + seconds: depositor[1] + }; + }); +} export function proposals (api: ApiInterfaceRx): () => Observable { return memo((): Observable => - api.query.democracy - .publicProps>>() - .pipe( - switchMap((proposals) => - combineLatest([ - of(proposals), - combineLatest( - ...proposals.map(([, hash]) => - api.query.democracy.preimages(hash) - ) - ) - ]) - ), - switchMap(([proposals, preimages]) => - combineLatest([ - of(proposals), - of(preimages), - combineLatest( - ...proposals.map(([index]) => - api.query.democracy.depositOf(index) - ) - ) - ]) - ), - map(([proposals, _preImages, _depositors]): DeriveProposal[] => - proposals - .filter(([, , proposer], index): boolean => - !!(_preImages[index]?.isSome) && !!(_depositors[index]?.isSome) && !proposer.isEmpty - ) - .map(([propIndex, hash, proposer], index): DeriveProposal => { - const preImage = _preImages[index].unwrapOr(null); - const depositors = _depositors[index].unwrap(); - - return { - balance: depositors[0], - hash, - index: propIndex, - preimage: preImage - ? { - at: preImage[3], - balance: preImage[2], - proposer: preImage[1] - } - : undefined, - proposal: preImage - ? createType(api.registry, 'Proposal', preImage[0].toU8a(true)) - : undefined, - proposer, - seconds: depositors[1] - }; - }) + api.query.democracy?.publicProps + ? api.query.democracy + .publicProps() + .pipe( + switchMap((proposals) => + combineLatest([ + of(proposals), + api.query.democracy.preimages.multi(proposals.map(([, hash]): Hash => hash)), + api.query.democracy.depositOf.multi(proposals.map(([index]): PropIndex => index)) + ]) + ), + map(([proposals, preimages, depositors]): DeriveProposal[] => + parse(api, { depositors, proposals, preimages }) + ) ) - ) + : of([] as DeriveProposal[]) ); } diff --git a/packages/api-derive/src/democracy/referendums.ts b/packages/api-derive/src/democracy/referendums.ts index f72fc985c1..c78584f4e7 100644 --- a/packages/api-derive/src/democracy/referendums.ts +++ b/packages/api-derive/src/democracy/referendums.ts @@ -14,18 +14,21 @@ import { memo } from '../util'; export function referendums (api: ApiInterfaceRx): () => Observable { return memo((): Observable => - api.queryMulti<[ReferendumIndex, ReferendumIndex]>([ - api.query.democracy.nextTally, - api.query.democracy.referendumCount - ]).pipe( - switchMap(([nextTally, referendumCount]): Observable => - referendumCount && nextTally && referendumCount.gt(nextTally) && referendumCount.gtn(0) - ? api.derive.democracy.referendumInfos( - [...Array(referendumCount.sub(nextTally).toNumber())].map((_, i): BN => - nextTally.addn(i) + api.query.democracy?.nextTally + ? api.queryMulti<[ReferendumIndex, ReferendumIndex]>([ + api.query.democracy.nextTally, + api.query.democracy.referendumCount + ]).pipe( + switchMap(([nextTally, referendumCount]): Observable => + referendumCount?.gt(nextTally) && referendumCount?.gtn(0) + ? api.derive.democracy.referendumInfos( + [...Array(referendumCount.sub(nextTally).toNumber())].map((_, i): BN => + nextTally.addn(i) + ) ) - ) - : of([]) + : of([]) + ) ) - )); + : of([] as DerivedReferendum[]) + ); } diff --git a/packages/types/src/codec/create/registry.ts b/packages/types/src/codec/create/registry.ts index 896eaaca08..9786e2e5b7 100644 --- a/packages/types/src/codec/create/registry.ts +++ b/packages/types/src/codec/create/registry.ts @@ -39,7 +39,7 @@ function decorateEvents (registry: Registry, metadata: RegistryMetadata, metadat console.error(error); } - metadataEvents[eventIndex.toString()] = class extends EventData { + metadataEvents[u8aToHex(eventIndex)] = class extends EventData { constructor (registry: Registry, value: Uint8Array) { super(registry, Types, value, typeDef, meta, sectionName, methodName); } @@ -55,7 +55,7 @@ function decorateExtrinsics (registry: Registry, metadata: RegistryMetadata, met // decorate the extrinsics Object.values(extrinsics).forEach((methods): void => Object.values(methods).forEach((method): void => { - metadataCalls[method.callIndex.toString()] = method; + metadataCalls[u8aToHex(method.callIndex)] = method; }) ); } @@ -88,15 +88,18 @@ export class TypeRegistry implements Registry { public findMetaCall (callIndex: Uint8Array): CallFunction { assert(Object.keys(this._metadataCalls).length > 0, 'Calling registry.findMetaCall before metadata has been attached.'); - return this._metadataCalls[callIndex.toString()] || FN_UNKNOWN; + const hexIndex = u8aToHex(callIndex); + + return this._metadataCalls[hexIndex] || FN_UNKNOWN; } public findMetaEvent (eventIndex: Uint8Array): Constructor { assert(Object.keys(this._metadataEvents).length > 0, 'Calling registry.findMetaEvent before metadata has been attached.'); - const Event = this._metadataEvents[eventIndex.toString()]; + const hexIndex = u8aToHex(eventIndex); + const Event = this._metadataEvents[hexIndex]; - assert(!isUndefined(Event), `Unable to find Event with index ${u8aToHex(eventIndex)}`); + assert(!isUndefined(Event), `Unable to find Event with index ${hexIndex}`); return Event; }