Add DispatchInfo (#1601)
* Add DispatchInfo * Cleanup metadata decoration * Assert for injection * Appropriate metadata injection * Fix tests
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 =>
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user