Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Use correct registry when creating calls; Remove usage of derive.chain.getBlock #391

Merged
merged 3 commits into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
"test": "jest --silent"
},
"dependencies": {
"@polkadot/api": "^3.3.2",
"@polkadot/apps-config": "^0.74.1",
"@polkadot/api": "^3.4.1",
"@polkadot/apps-config": "^0.75.1",
"@polkadot/util-crypto": "^5.2.3",
"@substrate/calc": "^0.1.3",
"confmgr": "^1.0.6",
Expand All @@ -47,14 +47,14 @@
"winston": "^3.3.3"
},
"devDependencies": {
"@types/express": "^4.17.9",
"@types/express-serve-static-core": "^4.17.17",
"@types/express": "^4.17.11",
"@types/express-serve-static-core": "^4.17.18",
"@types/http-errors": "^1.6.3",
"@types/jest": "^26.0.19",
"@types/jest": "^26.0.20",
"@types/morgan": "^1.9.2",
"@types/triple-beam": "^1.3.2",
"@typescript-eslint/eslint-plugin": "4.12.0",
"@typescript-eslint/parser": "4.12.0",
"@typescript-eslint/eslint-plugin": "4.13.0",
"@typescript-eslint/parser": "4.13.0",
"eslint": "^7.17.0",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-prettier": "^3.3.1",
Expand Down
4 changes: 2 additions & 2 deletions src/services/blocks/BlocksService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('BlocksService', () => {
(undefined as unknown) as GenericExtrinsic
);

mockApi.derive.chain.getBlock = (() =>
mockApi.rpc.chain.getBlock = (() =>
Promise.resolve().then(() => {
return {
block: mockBlock789629BadExt,
Expand All @@ -68,7 +68,7 @@ describe('BlocksService', () => {
)
);

mockApi.derive.chain.getBlock = (getBlock as unknown) as GetBlock;
mockApi.rpc.chain.getBlock = (getBlock as unknown) as GetBlock;
});
});

Expand Down
47 changes: 35 additions & 12 deletions src/services/blocks/BlocksService.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { ApiPromise } from '@polkadot/api';
import { SignedBlockExtended } from '@polkadot/api-derive/type';
import { GenericCall, Struct } from '@polkadot/types';
import { AbstractInt } from '@polkadot/types/codec/AbstractInt';
import {
AccountId,
Block,
BlockHash,
Digest,
DispatchInfo,
EventRecord,
Hash,
Expand Down Expand Up @@ -45,24 +46,19 @@ export class BlocksService extends AbstractService {
): Promise<IBlock> {
const { api } = this;

let block;
let events;
let author;
let block, events, sessionValidators;
if (typeof api.query.session?.validators?.at === 'function') {
// `api.derive.chain.getBlock` requires that `api.query.session?.validators?.at`
// is a function in order to query the validator set to pull out the author
// see: https://github.com/polkadot-js/api/blob/master/packages/api-derive/src/chain/getBlock.ts#L31
[{ author, block }, events] = await Promise.all([
api.derive.chain.getBlock(hash) as Promise<SignedBlockExtended>,
[{ block }, events, sessionValidators] = await Promise.all([
api.rpc.chain.getBlock(hash),
this.fetchEvents(api, hash),
api.query.session.validators.at(hash),
]);
} else {
[{ block }, events] = await Promise.all([
api.rpc.chain.getBlock(hash),
this.fetchEvents(api, hash),
]);
}
const authorId = author;

const {
parentHash,
Expand All @@ -72,9 +68,11 @@ export class BlocksService extends AbstractService {
digest,
} = block.header;

const logs = digest.logs.map((log) => {
const { type, index, value } = log;
const authorId = sessionValidators
? this.extractAuthor(sessionValidators, digest)
: undefined;
Comment on lines +71 to +73
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does extractAuthor return? If it returns undefined this ternary isn't needed.

Suggested change
const authorId = sessionValidators
? this.extractAuthor(sessionValidators, digest)
: undefined;
const authorId = this.extractAuthor(sessionValidators, digest);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We just need something so TS does not complain since it knows sessionValidators may be undefined.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eew, so you're saying we must do like const authorId = this.extractAuthor(sessionValidators, digest) || undefined; just to appease the compiler? :/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but we need to check before we call extractAuthor, because extractAuthor requires that the type of the sessionValidators param be Array<AccountId>. I agree with the compiler here because sending down undefined where only an array is expected could lead to issues at runtime.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean. But is it not an error if sessionValidators is undefined (or an empty array)? Like, shouldn't we bail before we get here if that's the case?


const logs = digest.logs.map(({ type, index, value }) => {
return { type, index, value };
});

Expand Down Expand Up @@ -513,4 +511,29 @@ export class BlocksService extends AbstractService {
args: newArgs,
};
}

// Almost exact mimic of https://github.com/polkadot-js/api/blob/e51e89df5605b692033df864aa5ab6108724af24/packages/api-derive/src/type/util.ts#L6
// but we save a call to `getHeader` by hardcoding the logic here and using the digest from the blocks header.
private extractAuthor(
sessionValidators: AccountId[],
digest: Digest
): AccountId | undefined {
const [pitem] = digest.logs.filter(({ type }) => type === 'PreRuntime');
// extract from the substrate 2.0 PreRuntime digest
if (pitem) {
const [engine, data] = pitem.asPreRuntime;
return engine.extractAuthor(data, sessionValidators);
} else {
const [citem] = digest.logs.filter(
({ type }) => type === 'Consensus'
);
// extract author from the consensus (substrate 1.0, digest)
if (citem) {
const [engine, data] = citem.asConsensus;
return engine.extractAuthor(data, sessionValidators);
}
}

return undefined;
}
}
Loading