Add DispatchInfo (#1601)

* Add DispatchInfo

* Cleanup metadata decoration

* Assert for injection

* Appropriate metadata injection

* Fix tests
This commit is contained in:
Jaco Greeff
2019-11-23 12:15:36 +01:00
committed by GitHub
parent 114c437671
commit 7f39c573ce
5 changed files with 64 additions and 32 deletions
+45 -28
View File
@@ -18,6 +18,47 @@ const FN_UNKNOWN: Partial<CallFunction> = {
section: 'unknown'
};
// create event classes from metadata
function decorateEvents (registry: Registry, metadata: RegistryMetadata, metadataEvents: Record<string, Constructor<EventData>>): void {
// decorate the events
metadata.asLatest.modules
.filter(({ events }): boolean => events.isSome)
.forEach((section, sectionIndex): void => {
const sectionName = stringCamelCase(section.name.toString());
section.events.unwrap().forEach((meta, methodIndex): void => {
const methodName = meta.name.toString();
const eventIndex = new Uint8Array([sectionIndex, methodIndex]);
const typeDef = meta.args.map((arg): TypeDef => getTypeDef(arg.toString()));
let Types: Constructor<Codec>[] = [];
try {
Types = typeDef.map((typeDef): Constructor<Codec> => getTypeClass(registry, typeDef));
} catch (error) {
console.error(error);
}
metadataEvents[eventIndex.toString()] = class extends EventData {
constructor (registry: Registry, value: Uint8Array) {
super(registry, Types, value, typeDef, meta, sectionName, methodName);
}
};
});
});
}
// create extrinsic mapping from metadata
function decorateExtrinsics (registry: Registry, metadata: RegistryMetadata, metadataCalls: Record<string, CallFunction>): void {
const extrinsics = extrinsicsFromMeta(registry, metadata);
// decorate the extrinsics
Object.values(extrinsics).forEach((methods): void =>
Object.values(methods).forEach((method): void => {
metadataCalls[method.callIndex.toString()] = method;
})
);
}
export class TypeRegistry implements Registry {
private _classes: Map<string, Constructor> = new Map();
@@ -50,6 +91,8 @@ export class TypeRegistry implements Registry {
}
public findMetaEvent (eventIndex: Uint8Array): Constructor<EventData> {
assert(Object.keys(this._metadataEvents).length > 0, 'Calling registry.findMetaEvent before metadata has been attached.');
const Event = this._metadataEvents[eventIndex.toString()];
assert(!isUndefined(Event), `Unable to find Event with index ${u8aToHex(eventIndex)}`);
@@ -147,33 +190,7 @@ export class TypeRegistry implements Registry {
// sets the metadata
public setMetadata (metadata: RegistryMetadata): void {
const extrinsics = extrinsicsFromMeta(this, metadata);
// decorate the extrinsics
Object.values(extrinsics).forEach((methods): void =>
Object.values(methods).forEach((method): void => {
this._metadataCalls[method.callIndex.toString()] = method;
})
);
// decorate the events
metadata.asLatest.modules
.filter(({ events }): boolean => events.isSome)
.forEach((section, sectionIndex): void => {
const sectionName = stringCamelCase(section.name.toString());
section.events.unwrap().forEach((meta, methodIndex): void => {
const methodName = meta.name.toString();
const eventIndex = new Uint8Array([sectionIndex, methodIndex]);
const typeDef = meta.args.map((arg): TypeDef => getTypeDef(arg.toString()));
const Types = typeDef.map((typeDef): Constructor<Codec> => getTypeClass(this, typeDef));
this._metadataEvents[eventIndex.toString()] = class extends EventData {
constructor (registry: Registry, value: Uint8Array) {
super(registry, Types, value, typeDef, meta, sectionName, methodName);
}
};
});
});
decorateExtrinsics(this, metadata, this._metadataCalls);
decorateEvents(this, metadata, this._metadataEvents);
}
}
+3 -3
View File
@@ -23,6 +23,9 @@ const UNCONSTRUCTABLE = [
const registry = new TypeRegistry();
// eslint-disable-next-line no-new
new Metadata(registry, metadataStatic);
function testTypes (type: string, typeNames: string[]): void {
describe(type, (): void => {
describe(`${type}:: default creation`, (): void => {
@@ -41,9 +44,6 @@ function testTypes (type: string, typeNames: string[]): void {
});
describe(`${type}:: default creation (empty bytes)`, (): void => {
// eslint-disable-next-line no-new
new Metadata(registry, metadataStatic);
typeNames.forEach((name): void => {
it(`creates an empty ${name} (from empty bytes)`, (): void => {
const constructFn = (): Codec =>
+4 -1
View File
@@ -3,7 +3,7 @@
import { Compact, Option, Vec } from '@polkadot/types/codec';
import { Bytes, Data, Fixed64, H160, H256, H512, Null, StorageData, StorageHasher, StorageKey, Text, Type, U256, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, Moment, MortalEra, MultiSignature, Origin, Perbill, Permill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, Moment, MortalEra, MultiSignature, Origin, Perbill, Permill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { InclusionHeight, Uncle, UncleEntryItem } from '@polkadot/types/interfaces/authorship';
import { RawAuraPreDigest } from '@polkadot/types/interfaces/aura';
import { BabeAuthorityWeight, BabeBlockWeight, BabeWeight, MaybeVrf, RawBabePreDigest, RawBabePreDigest0to159, RawBabePreDigestCompat, RawBabePreDigestPrimary, RawBabePreDigestPrimary0to159, RawBabePreDigestSecondary, RawBabePreDigestSecondary0to159, SlotNumber, VrfData, VrfProof } from '@polkadot/types/interfaces/babe';
@@ -167,6 +167,9 @@ export interface InterfaceRegistry {
DispatchClass: DispatchClass;
'Option<DispatchClass>': Option<DispatchClass>;
'Vec<DispatchClass>': Vec<DispatchClass>;
DispatchInfo: DispatchInfo;
'Option<DispatchInfo>': Option<DispatchInfo>;
'Vec<DispatchInfo>': Vec<DispatchInfo>;
Extrinsic: Extrinsic;
'Option<Extrinsic>': Option<Extrinsic>;
'Vec<Extrinsic>': Vec<Extrinsic>;
@@ -20,6 +20,10 @@ export default {
DispatchClass: {
_enum: ['Normal', 'Operational']
},
DispatchInfo: {
weight: 'Weight',
class: 'DispatchClass'
},
Extrinsic: 'GenericExtrinsic',
ExtrinsicEra: 'GenericExtrinsicEra',
ExtrinsicPayload: 'GenericExtrinsicPayload',
@@ -55,6 +55,14 @@ export interface DispatchClass extends Enum {
readonly isOperational: boolean;
}
/** Struct */
export interface DispatchInfo extends Struct {
/** Weight */
readonly weight: Weight;
/** DispatchClass */
readonly class: DispatchClass;
}
/** Uint8Array, Codec */
export interface EcdsaSignature extends Uint8Array, Codec {}