Use Si V1 in contracts (w/ PortableRegistry usage) (#3988)

* Use Si V1 in contracts (w/ PortableRegistry usage)

* Type id lookups

* Fix build & linting

* Remove extra .toNumber() (VSCode has gone crazy)

* v1 tests

* Cleanup parsing

* Explicit type cast for v1 types

* Unneeded toNumber

* Align events exposure with messages/constructors

* dedupe

* Re-add typedef extraction tests

* with typedefs

* Override for always primitives

* displayName improvements

* Versioned project

* New structure

* Fixes

* Cleanups

* Ensure API registry is the default used

* Adjust arg & return encoding/decoding

* Recursive contract

* DoNotConstruct to Si type
This commit is contained in:
Jaco
2021-10-11 12:50:09 +03:00
committed by GitHub
parent 6a12aceae2
commit d053b86e23
83 changed files with 2696 additions and 2497 deletions
@@ -226,6 +226,10 @@ declare module '@polkadot/types/lookup' {
readonly weightLimit: XcmV2WeightLimit;
} & Struct;
readonly isRefundSurplus: boolean;
readonly isSetErrorHandler: boolean;
readonly asSetErrorHandler: XcmV2Xcm;
readonly isSetAppendix: boolean;
readonly asSetAppendix: XcmV2Xcm;
readonly isClearError: boolean;
readonly isClaimAsset: boolean;
readonly asClaimAsset: {
+7 -1
View File
@@ -17,7 +17,7 @@ import type { EthereumAddress, StatementKind } from '@polkadot/types/interfaces/
import type { CollectiveOrigin, MemberCount, ProposalIndex, Votes, VotesTo230 } from '@polkadot/types/interfaces/collective';
import type { AuthorityId, RawVRFOutput } from '@polkadot/types/interfaces/consensus';
import type { AliveContractInfo, CodeHash, ContractCallRequest, ContractExecResult, ContractExecResultErr, ContractExecResultErrModule, ContractExecResultOk, ContractExecResultResult, ContractExecResultSuccessTo255, ContractExecResultSuccessTo260, ContractExecResultTo255, ContractExecResultTo260, ContractExecResultTo267, ContractInfo, ContractInstantiateResult, ContractInstantiateResultTo267, ContractStorageKey, DeletedContract, ExecReturnValue, Gas, HostFnWeights, HostFnWeightsTo264, InstantiateRequest, InstantiateReturnValue, InstantiateReturnValueTo267, InstructionWeights, Limits, LimitsTo264, PrefabWasmModule, RentProjection, Schedule, ScheduleTo212, ScheduleTo258, ScheduleTo264, SeedOf, TombstoneContractInfo, TrieId } from '@polkadot/types/interfaces/contracts';
import type { ContractConstructorSpec, ContractContractSpec, ContractCryptoHasher, ContractDiscriminant, ContractDisplayName, ContractEventParamSpec, ContractEventSpec, ContractLayoutArray, ContractLayoutCell, ContractLayoutEnum, ContractLayoutHash, ContractLayoutHashingStrategy, ContractLayoutKey, ContractLayoutStruct, ContractLayoutStructField, ContractMessageParamSpec, ContractMessageSpec, ContractProject, ContractProjectContract, ContractProjectSource, ContractSelector, ContractStorageLayout, ContractTypeSpec } from '@polkadot/types/interfaces/contractsAbi';
import type { ContractConstructorSpec, ContractContractSpec, ContractCryptoHasher, ContractDiscriminant, ContractDisplayName, ContractEventParamSpec, ContractEventSpec, ContractLayoutArray, ContractLayoutCell, ContractLayoutEnum, ContractLayoutHash, ContractLayoutHashingStrategy, ContractLayoutKey, ContractLayoutStruct, ContractLayoutStructField, ContractMessageParamSpec, ContractMessageSpec, ContractMetadata, ContractMetadataLatest, ContractMetadataV0, ContractMetadataV1, ContractProject, ContractProjectContract, ContractProjectInfo, ContractProjectSource, ContractProjectV0, ContractSelector, ContractStorageLayout, ContractTypeSpec } from '@polkadot/types/interfaces/contractsAbi';
import type { FundIndex, FundInfo, LastContribution, TrieIndex } from '@polkadot/types/interfaces/crowdloan';
import type { ConfigData, MessageId, OverweightIndex, PageCounter, PageIndexData } from '@polkadot/types/interfaces/cumulus';
import type { AccountVote, AccountVoteSplit, AccountVoteStandard, Conviction, Delegations, PreimageStatus, PreimageStatusAvailable, PriorLock, PropIndex, Proposal, ProxyState, ReferendumIndex, ReferendumInfo, ReferendumInfoFinished, ReferendumInfoTo239, ReferendumStatus, Tally, Voting, VotingDelegating, VotingDirect, VotingDirectVote } from '@polkadot/types/interfaces/democracy';
@@ -239,9 +239,15 @@ declare module '@polkadot/types/types/registry' {
ContractLayoutStructField: ContractLayoutStructField;
ContractMessageParamSpec: ContractMessageParamSpec;
ContractMessageSpec: ContractMessageSpec;
ContractMetadata: ContractMetadata;
ContractMetadataLatest: ContractMetadataLatest;
ContractMetadataV0: ContractMetadataV0;
ContractMetadataV1: ContractMetadataV1;
ContractProject: ContractProject;
ContractProjectContract: ContractProjectContract;
ContractProjectInfo: ContractProjectInfo;
ContractProjectSource: ContractProjectSource;
ContractProjectV0: ContractProjectV0;
ContractSelector: ContractSelector;
ContractStorageKey: ContractStorageKey;
ContractStorageLayout: ContractStorageLayout;
+7 -1
View File
@@ -121,6 +121,8 @@ export class TypeRegistry implements Registry {
#definitions = new Map<string, string>();
#lookup?: PortableRegistry;
#metadata?: MetadataLatest;
readonly #metadataCalls: Record<string, CallFunction> = {};
@@ -223,7 +225,7 @@ export class TypeRegistry implements Registry {
}
public get lookup (): PortableRegistry {
return this.metadata.lookup;
return this.#lookup || this.metadata.lookup;
}
public get metadata (): MetadataLatest {
@@ -442,6 +444,10 @@ export class TypeRegistry implements Registry {
this.#knownTypes = knownTypes;
}
setLookup (lookup: PortableRegistry): void {
this.#lookup = lookup;
}
// sets the metadata
public setMetadata (metadata: Metadata, signedExtensions?: string[], userExtensions?: ExtDef): void {
this.#metadata = metadata.asLatest;
@@ -228,9 +228,20 @@ function extractNames (lookup: GenericPortableRegistry, types: PortableType[]):
return names;
}
// types have an id, which means they are to be named by
// the specified id - ensure we have a mapping lookup for these
function extractTypeMap (types: PortableType[]): Record<number, PortableType> {
return types.reduce<Record<number, PortableType>>((types, pt) => {
types[pt.id.toNumber()] = pt;
return types;
}, {});
}
export class GenericPortableRegistry extends Struct {
#names: Record<number, string>;
#typeDefs: Record<number, TypeDef> = {};
#types: Record<number, PortableType>;
constructor (registry: Registry, value?: Uint8Array) {
super(registry, {
@@ -238,6 +249,7 @@ export class GenericPortableRegistry extends Struct {
}, value);
this.#names = extractNames(this, this.types);
this.#types = extractTypeMap(this.types);
}
/**
@@ -258,7 +270,9 @@ export class GenericPortableRegistry extends Struct {
* @description Finds a specific type in the registry
*/
public getSiType (lookupId: SiLookupTypeId | string | number): SiType {
const found = this.types[this.#getLookupId(lookupId)];
// NOTE catch-22 - this may already be used as part of the constructor, so
// ensure that we have actually initialized it correctly
const found = (this.#types || this.types)[this.#getLookupId(lookupId)];
assert(found, () => `PortableRegistry: Unable to find type with lookupId ${lookupId.toString()}`);
@@ -314,7 +328,7 @@ export class GenericPortableRegistry extends Struct {
const lookupIndex = lookupId.toNumber();
// Setup for a lookup on complex types
return [TypeDefInfo.Enum, TypeDefInfo.Struct].includes(typeDef.info) && typeDef.lookupName
return [TypeDefInfo.DoNotConstruct, TypeDefInfo.Enum, TypeDefInfo.Struct].includes(typeDef.info) && typeDef.lookupName
? {
docs: typeDef.docs,
info: TypeDefInfo.Si,
@@ -119,13 +119,16 @@ function convertDef (registry: Registry, { def, path }: Si0Type): Si1TypeDef {
}
export function toV1 (registry: Registry, types: Si0Type[]): PortableType[] {
return types.map((t, id) =>
return types.map((t, index) =>
registry.createType('PortableType', {
id,
// offsets are +1 from v0
id: index + 1,
type: {
def: convertDef(registry, t),
docs: [],
params: t.params.map((p) => p.toNumber()),
params: t.params.map((p) => registry.createType('Si1TypeParameter', {
type: p.toNumber()
})),
path: t.path.map((p) => p.toString())
}
})
@@ -19,7 +19,7 @@ const layout = {
},
ContractLayoutCell: {
key: 'ContractLayoutKey',
ty: 'Si0LookupTypeId'
ty: 'SiLookupTypeId'
},
ContractLayoutEnum: {
dispatchKey: 'ContractLayoutKey',
@@ -67,7 +67,7 @@ const spec = {
events: 'Vec<ContractEventSpec>',
docs: 'Vec<Text>'
},
ContractDisplayName: 'Si0Path',
ContractDisplayName: 'SiPath',
ContractEventParamSpec: {
name: 'Text',
indexed: 'bool',
@@ -94,28 +94,47 @@ const spec = {
},
ContractSelector: '[u8; 4]',
ContractTypeSpec: {
type: 'Si0LookupTypeId',
type: 'SiLookupTypeId',
displayName: 'ContractDisplayName'
}
};
const ContractMetadataV0 = {
types: 'Vec<Si0Type>',
spec: 'ContractContractSpec'
};
const ContractMetadataV1 = {
types: 'Vec<PortableType>',
spec: 'ContractContractSpec'
};
const ContractProjectInfo = {
source: 'ContractProjectSource',
contract: 'ContractProjectContract'
};
export default {
rpc: {},
types: {
...layout,
...spec,
ContractProject: {
// added by ABI serialization
metadataVersion: 'Text',
source: 'ContractProjectSource',
contract: 'ContractProjectContract',
// expanded scale registry: RegistryReadOnly
// NOTE Previous generation of the Si0Type definition
types: 'Vec<Si0Type>',
// renamed from layout (ignored for now, incomplete)
// storage: 'ContractStorageLayout',
spec: 'ContractContractSpec'
ContractProjectInfo,
ContractMetadataV0,
ContractMetadataV1,
ContractMetadata: {
_enum: {
V0: 'ContractMetadataV0',
V1: 'ContractMetadataV1'
}
},
ContractMetadataLatest: 'ContractMetadataV1',
ContractProjectV0: {
metadataVersion: 'Text',
...ContractProjectInfo,
...ContractMetadataV0
},
ContractProject: '(ContractProjectInfo, ContractMetadata)',
ContractProjectContract: {
_alias: {
docs: 'documentation'
@@ -2,7 +2,9 @@
/* eslint-disable */
import type { BTreeMap, Bytes, Enum, Option, Raw, Struct, Text, U8aFixed, Vec, bool, u32, u64 } from '@polkadot/types';
import type { Si0LookupTypeId, Si0Path, Si0Type } from '@polkadot/types/interfaces/scaleInfo';
import type { PortableType } from '@polkadot/types/interfaces/metadata';
import type { Si0Type, SiLookupTypeId, SiPath } from '@polkadot/types/interfaces/scaleInfo';
import type { ITuple } from '@polkadot/types/types';
/** @name ContractConstructorSpec */
export interface ContractConstructorSpec extends Struct {
@@ -31,7 +33,7 @@ export interface ContractCryptoHasher extends Enum {
export interface ContractDiscriminant extends u32 {}
/** @name ContractDisplayName */
export interface ContractDisplayName extends Si0Path {}
export interface ContractDisplayName extends SiPath {}
/** @name ContractEventParamSpec */
export interface ContractEventParamSpec extends Struct {
@@ -59,7 +61,7 @@ export interface ContractLayoutArray extends Struct {
/** @name ContractLayoutCell */
export interface ContractLayoutCell extends Struct {
readonly key: ContractLayoutKey;
readonly ty: Si0LookupTypeId;
readonly ty: SiLookupTypeId;
}
/** @name ContractLayoutEnum */
@@ -113,15 +115,32 @@ export interface ContractMessageSpec extends Struct {
readonly docs: Vec<Text>;
}
/** @name ContractProject */
export interface ContractProject extends Struct {
readonly metadataVersion: Text;
readonly source: ContractProjectSource;
readonly contract: ContractProjectContract;
/** @name ContractMetadata */
export interface ContractMetadata extends Enum {
readonly isV0: boolean;
readonly asV0: ContractMetadataV0;
readonly isV1: boolean;
readonly asV1: ContractMetadataV1;
}
/** @name ContractMetadataLatest */
export interface ContractMetadataLatest extends ContractMetadataV1 {}
/** @name ContractMetadataV0 */
export interface ContractMetadataV0 extends Struct {
readonly types: Vec<Si0Type>;
readonly spec: ContractContractSpec;
}
/** @name ContractMetadataV1 */
export interface ContractMetadataV1 extends Struct {
readonly types: Vec<PortableType>;
readonly spec: ContractContractSpec;
}
/** @name ContractProject */
export interface ContractProject extends ITuple<[ContractProjectInfo, ContractMetadata]> {}
/** @name ContractProjectContract */
export interface ContractProjectContract extends Struct {
readonly name: Text;
@@ -134,6 +153,12 @@ export interface ContractProjectContract extends Struct {
readonly license: Option<Text>;
}
/** @name ContractProjectInfo */
export interface ContractProjectInfo extends Struct {
readonly source: ContractProjectSource;
readonly contract: ContractProjectContract;
}
/** @name ContractProjectSource */
export interface ContractProjectSource extends Struct {
readonly wasmHash: U8aFixed;
@@ -142,6 +167,15 @@ export interface ContractProjectSource extends Struct {
readonly wasm: Raw;
}
/** @name ContractProjectV0 */
export interface ContractProjectV0 extends Struct {
readonly metadataVersion: Text;
readonly source: ContractProjectSource;
readonly contract: ContractProjectContract;
readonly types: Vec<Si0Type>;
readonly spec: ContractContractSpec;
}
/** @name ContractSelector */
export interface ContractSelector extends U8aFixed {}
@@ -161,7 +195,7 @@ export interface ContractStorageLayout extends Enum {
/** @name ContractTypeSpec */
export interface ContractTypeSpec extends Struct {
readonly type: Si0LookupTypeId;
readonly type: SiLookupTypeId;
readonly displayName: ContractDisplayName;
}
+1
View File
@@ -146,6 +146,7 @@ export interface Registry {
register (arg1: string | Constructor | RegistryTypes, arg2?: Constructor): void;
setChainProperties (properties?: ChainProperties): void;
setHasher (hasher?: CodecHasher | null): void;
setLookup (lookup: PortableRegistry): void;
setMetadata (metadata: Metadata, signedExtensions?: string[], userExtensions?: ExtDef): void;
setSignedExtensions (signedExtensions?: string[], userExtensions?: ExtDef): void;
}