Skip to content

Commit

Permalink
Mark api.query.<section>.<method>.at as deprecated (#4023)
Browse files Browse the repository at this point in the history
* Use api.at internally for sizeAt/entriesAt/keysAt

* Remove debug logs

* Mark api.query.<section>.<method>.at as deprecated

* formatting

* @deprecated formatting

* commenting
  • Loading branch information
jacogr authored Oct 6, 2021
1 parent 407aca3 commit affa6ab
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 59 deletions.
23 changes: 11 additions & 12 deletions packages/api-derive/src/chain/getBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,19 @@ import { memo } from '../util';
* ```
*/
export function getBlock (instanceId: string, api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<SignedBlockExtended | undefined> {
return memo(instanceId, (hash: Uint8Array | string): Observable<SignedBlockExtended | undefined> =>
// we get the block first, setting up the registry
api.rpc.chain.getBlock(hash).pipe(
switchMap((signedBlock) =>
return memo(instanceId, (blockHash: Uint8Array | string): Observable<SignedBlockExtended | undefined> =>
api.queryAt(blockHash).pipe(
switchMap((queryAt) =>
combineLatest([
api.query.system.events.at(hash),
api.query.session
? api.query.session.validators.at(hash)
api.rpc.chain.getBlock(blockHash),
queryAt.system.events(),
queryAt.session
? queryAt.session.validators()
: of([])
]).pipe(
map(([events, validators]) =>
createSignedBlockExtended(api.registry, signedBlock, events, validators)
)
)
])
),
map(([signedBlock, events, validators]) =>
createSignedBlockExtended(api.registry, signedBlock, events, validators)
),
catchError((): Observable<undefined> =>
// where rpc.chain.getHeader throws, we will land here - it can happen that
Expand Down
27 changes: 12 additions & 15 deletions packages/api-derive/src/chain/getHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,11 @@ import type { ApiInterfaceRx } from '@polkadot/api/types';
import type { AccountId } from '@polkadot/types/interfaces';
import type { HeaderExtended } from '../type/types';

import { catchError, map, of, switchMap } from 'rxjs';
import { catchError, combineLatest, map, of, switchMap } from 'rxjs';

import { createHeaderExtended } from '../type';
import { memo } from '../util';

function _getValidators (api: ApiInterfaceRx, hash: Uint8Array | string): Observable<AccountId[]> {
return api.query.session
? api.query.session.validators.at(hash)
: of([] as AccountId[]);
}

/**
* @name getHeader
* @param {( Uint8Array | string )} hash - A block hash as U8 array or string.
Expand All @@ -33,14 +27,17 @@ function _getValidators (api: ApiInterfaceRx, hash: Uint8Array | string): Observ
*/
export function getHeader (instanceId: string, api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<HeaderExtended | undefined> {
return memo(instanceId, (hash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
// we get the header first, setting up the registry
api.rpc.chain.getHeader(hash).pipe(
switchMap((header) =>
_getValidators(api, hash).pipe(
map((validators) =>
createHeaderExtended(header.registry, header, validators)
)
)
api.queryAt(hash).pipe(
switchMap((queryAt) =>
combineLatest([
api.rpc.chain.getHeader(hash),
queryAt.session
? queryAt.session.validators()
: of([] as AccountId[])
])
),
map(([header, validators]) =>
createHeaderExtended(header.registry, header, validators)
),
catchError((): Observable<undefined> =>
// where rpc.chain.getHeader throws, we will land here - it can happen that
Expand Down
21 changes: 12 additions & 9 deletions packages/api-derive/src/chain/subscribeNewBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { Observable } from 'rxjs';
import type { ApiInterfaceRx } from '@polkadot/api/types';
import type { SignedBlockExtended } from '../type/types';

import { map, switchMap } from 'rxjs';
import { combineLatest, map, of, switchMap } from 'rxjs';

import { createSignedBlockExtended } from '../type';
import { memo } from '../util';
Expand All @@ -21,16 +21,19 @@ export function subscribeNewBlocks (instanceId: string, api: ApiInterfaceRx): ()
const blockHash = header.createdAtHash || header.hash;

// we get the block first, setting up the registry
return api.rpc.chain.getBlock(blockHash).pipe(
switchMap((block) =>
api.query.system.events.at(blockHash).pipe(
map((events) =>
createSignedBlockExtended(block.registry, block, events, header.validators)
)
)
return api.queryAt(blockHash).pipe(
switchMap((queryAt) =>
combineLatest([
of(header),
api.rpc.chain.getBlock(blockHash),
queryAt.system.events()
])
)
);
})
}),
map(([header, block, events]) =>
createSignedBlockExtended(block.registry, block, events, header.validators)
)
)
);
}
22 changes: 10 additions & 12 deletions packages/api-derive/src/tx/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { Observable } from 'rxjs';
import type { ApiInterfaceRx } from '@polkadot/api/types';
import type { EventRecord, Hash, SignedBlock } from '@polkadot/types/interfaces';

import { map, switchMap } from 'rxjs';
import { combineLatest, map, switchMap } from 'rxjs';

import { memo } from '../util';

Expand All @@ -15,17 +15,15 @@ interface Result {
}

export function events (instanceId: string, api: ApiInterfaceRx): (at: Hash) => Observable<Result> {
return memo(instanceId, (at: Hash) =>
// we get the block first, setting up the registry
api.rpc.chain.getBlock(at).pipe(
switchMap((block) =>
api.query.system.events.at(at).pipe(
map((events): Result => ({
block,
events
}))
)
)
return memo(instanceId, (blockHash: Hash) =>
api.queryAt(blockHash).pipe(
switchMap((queryAt) =>
combineLatest([
api.rpc.chain.getBlock(blockHash),
queryAt.system.events()
])
),
map(([block, events]): Result => ({ block, events }))
)
);
}
10 changes: 4 additions & 6 deletions packages/api/src/base/Decorate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {

this.#instanceId = `${++instanceCounter}`;
this.#registry = options.source?.registry || options.registry || new TypeRegistry();
this._rx.queryAt = (blockHash: Uint8Array | string) =>
from(this.at(blockHash)).pipe(map((a) => a.rx.query));
this._rx.registry = this.#registry;

const thisProvider = options.source
Expand Down Expand Up @@ -453,8 +455,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {

decorated.at = decorateMethod((blockHash: Hash, ...args: unknown[]): Observable<Codec> =>
getQueryAt(blockHash).pipe(
switchMap((q) => q(...args))
));
switchMap((q) => q(...args))));

decorated.hash = decorateMethod((...args: unknown[]): Observable<Hash> =>
this._rpcCore.state.getStorageHash(getArgs(args)));
Expand All @@ -478,10 +479,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
decorated.sizeAt = decorateMethod((blockHash: Hash | Uint8Array | string, ...args: unknown[]): Observable<u64> =>
getQueryAt(blockHash).pipe(
switchMap((q) =>
this._rpcCore.state.getStorageSize(getArgs(args, q.creator.meta.registry), blockHash)
)
)
);
this._rpcCore.state.getStorageSize(getArgs(args, q.creator.meta.registry), blockHash))));

// .keys() & .entries() only available on map types
if (creator.iterKey && creator.meta.type.isMap) {
Expand Down
8 changes: 4 additions & 4 deletions packages/api/src/checkTypes.manual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ async function query (api: ApiPromise, pairs: TestKeyringMap): Promise<void> {
const bal2 = await api.query.balances.totalIssuance('WRONG_ARG'); // bal2 is Codec (wrong args)
const override = await api.query.balances.totalIssuance<Header>(); // override is still available
const oldBal = await api.query.balances.totalIssuance.at('abcd');
// It's hard to correctly type .multi. Expected: `Balance[]`, actual: Codec[].
// In the meantime, we can case with `<Balance>` (this is not available on recent chains)
const multi = await api.query.balances.freeBalance.multi([pairs.alice.address, pairs.bob.address]);
// For older queries we can cast with `<Balance>` (newer chain have multi typed)
const multia = await api.query.balances.freeBalance.multi<Balance>([pairs.alice.address, pairs.bob.address]);
const multib = await api.query.system.account.multi([pairs.alice.address, pairs.bob.address]);

console.log('query types:', bar, bal, bal2, override, oldBal, multi);
console.log('query types:', bar, bal, bal2, override, oldBal, multia, multib);

// check multi for unsub
const multiUnsub = await api.queryMulti([
Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// Augment the modules
import '@polkadot/api/augment';

import type { Observable } from 'rxjs';
import type { DeriveCustom, ExactDerive } from '@polkadot/api-derive';
import type { RpcInterface } from '@polkadot/rpc-core/types';
import type { ProviderInterface, ProviderInterfaceEmitted } from '@polkadot/rpc-provider/types';
Expand Down Expand Up @@ -94,6 +95,7 @@ export interface ApiInterfaceRx {
runtimeMetadata: Metadata;
runtimeVersion: RuntimeVersion;
query: QueryableStorage<'rxjs'>;
queryAt: (blockHash: Uint8Array | string) => Observable<QueryableStorage<'rxjs'>>;
queryMulti: QueryableStorageMulti<'rxjs'>;
rpc: DecoratedRpc<'rxjs', RpcInterface>;
tx: SubmittableExtrinsics<'rxjs'>;
Expand Down
16 changes: 15 additions & 1 deletion packages/api/src/types/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,28 @@ export interface QueryableStorageAt<ApiType extends ApiTypes> extends AugmentedQ
}

export interface StorageEntryBase<ApiType extends ApiTypes, F extends AnyFunction, A extends AnyTuple = AnyTuple> extends StorageEntryBaseAt<ApiType, F, A> {
/**
* @deprecated Use api.at(<blockHash>)
*/
at: <T extends Codec | any = ReturnCodec<F>>(hash: Hash | Uint8Array | string, ...args: Parameters<F>) => PromiseOrObs<ApiType, T>;
creator: StorageEntry;
/**
* @deprecated Use api.at(<blockHash>)
*/
entriesAt: <T extends Codec | any = ReturnCodec<F>, K extends AnyTuple = A>(hash: Hash | Uint8Array | string, ...args: DropLast<Parameters<F>>) => PromiseOrObs<ApiType, [StorageKey<K>, T][]>;
entriesPaged: <T extends Codec | any = ReturnCodec<F>, K extends AnyTuple = A>(opts: PaginationOptions<Parameters<F>[0]>) => PromiseOrObs<ApiType, [StorageKey<K>, T][]>;
/**
* @deprecated Use api.at(<blockHash>)
*/
keysAt: <K extends AnyTuple = A> (hash: Hash | Uint8Array | string, ...args: DropLast<Parameters<F>>) => PromiseOrObs<ApiType, StorageKey<K>[]>;
keysPaged: <K extends AnyTuple = A> (opts: PaginationOptions<Parameters<F>[0]>) => PromiseOrObs<ApiType, StorageKey<K>[]>;
// @deprecated The underlying RPC this been marked unsafe and is generally not exposed
/**
* @deprecated The underlying RPC this been marked unsafe and is generally not exposed
*/
range: <T extends Codec | any = ReturnCodec<F>>([from, to]: [Hash | Uint8Array | string, Hash | Uint8Array | string | undefined] | [Hash | Uint8Array | string], ...args: Parameters<F>) => PromiseOrObs<ApiType, [Hash, T][]>;
/**
* @deprecated Use api.at(<blockHash>)
*/
sizeAt: (hash: Hash | Uint8Array | string, ...args: Parameters<F>) => PromiseOrObs<ApiType, u64>;
multi: ApiType extends 'rxjs'
? StorageEntryObservableMulti<ReturnCodec<F>>
Expand Down

0 comments on commit affa6ab

Please sign in to comment.