From fcb2b324d1bae486ca7469298e94170ccfe18ea0 Mon Sep 17 00:00:00 2001 From: Daniel Shiposha Date: Fri, 16 Sep 2022 14:01:28 +0000 Subject: [PATCH] feat: add sudo/scheduler support to playgrounds, several minor additions --- --- a/tests/src/util/playgrounds/unique.dev.ts +++ b/tests/src/util/playgrounds/unique.dev.ts @@ -10,6 +10,7 @@ import {EventRecord} from '@polkadot/types/interfaces'; import {ICrossAccountId} from './types'; import {FrameSystemEventRecord} from '@polkadot/types/lookup'; +import {VoidFn} from '@polkadot/api/types'; export class SilentLogger { log(_msg: any, _level: any): void { } @@ -154,6 +155,8 @@ class ArrangeGroup { helper: DevUniqueHelper; + scheduledIdSlider = 0; + constructor(helper: DevUniqueHelper) { this.helper = helper; } @@ -297,6 +300,39 @@ const address = stringToU8a(('modl' + palletId).padEnd(32, '\0')); return encodeAddress(address); } + + async makeScheduledIds(num: number): Promise { + await this.helper.wait.noScheduledTasks(); + + function makeId(slider: number) { + const scheduledIdSize = 32; + const hexId = slider.toString(16); + const prefixSize = scheduledIdSize - hexId.length; + + const scheduledId = '0x' + '0'.repeat(prefixSize) + hexId; + + return scheduledId; + } + + const ids = []; + for (let i = 0; i < num; i++) { + ids.push(makeId(this.scheduledIdSlider)); + this.scheduledIdSlider += 1; + } + + return ids; + } + + async makeScheduledId(): Promise { + return (await this.makeScheduledIds(1))[0]; + } + + async captureEvents(eventSection: string, eventMethod: string): Promise { + const capture = new EventCapture(this.helper, eventSection, eventMethod); + await capture.startCapture(); + + return capture; + } } class MoonbeamAccountGroup { @@ -389,6 +425,24 @@ }); } + async noScheduledTasks() { + const api = this.helper.getApi(); + + // eslint-disable-next-line no-async-promise-executor + const promise = new Promise(async resolve => { + const unsubscribe = await api.rpc.chain.subscribeNewHeads(async () => { + const areThereScheduledTasks = await api.query.scheduler.lookup.entries(); + + if(areThereScheduledTasks.length == 0) { + unsubscribe(); + resolve(); + } + }); + }); + + return promise; + } + async event(maxBlocksToWait: number, eventSection: string, eventMethod: string) { // eslint-disable-next-line no-async-promise-executor const promise = new Promise(async (resolve) => { @@ -414,7 +468,6 @@ maxBlocksToWait--; } else { this.helper.logger.log(`Event \`${eventIdStr}\` is NOT found`); - unsubscribe(); resolve(null); } @@ -424,6 +477,45 @@ } } +class EventCapture { + helper: DevUniqueHelper; + eventSection: string; + eventMethod: string; + events: EventRecord[] = []; + unsubscribe: VoidFn | null = null; + + constructor( + helper: DevUniqueHelper, + eventSection: string, + eventMethod: string, + ) { + this.helper = helper; + this.eventSection = eventSection; + this.eventMethod = eventMethod; + } + + async startCapture() { + this.stopCapture(); + this.unsubscribe = await this.helper.getApi().query.system.events(eventRecords => { + const newEvents = eventRecords.filter(r => { + return r.event.section == this.eventSection && r.event.method == this.eventMethod; + }); + + this.events.push(...newEvents); + }); + } + + stopCapture() { + if (this.unsubscribe !== null) { + this.unsubscribe(); + } + } + + extractCapturedEvents() { + return this.events; + } +} + class AdminGroup { helper: UniqueHelper; --- a/tests/src/util/playgrounds/unique.ts +++ b/tests/src/util/playgrounds/unique.ts @@ -534,25 +534,27 @@ } async getPaymentInfo(signer: TSigner, tx: any, len: number | null) { - const signingInfo = await this.api!.derive.tx.signingInfo(signer.address); + const api = this.getApi(); + const signingInfo = await api.derive.tx.signingInfo(signer.address); // We need to sign the tx because // unsigned transactions does not have an inclusion fee tx.sign(signer, { - blockHash: this.api!.genesisHash, - genesisHash: this.api!.genesisHash, - runtimeVersion: this.api!.runtimeVersion, + blockHash: api.genesisHash, + genesisHash: api.genesisHash, + runtimeVersion: api.runtimeVersion, nonce: signingInfo.nonce, }); if (len === null) { return (await this.callRpc('api.rpc.payment.queryInfo', [tx.toHex()])) as RuntimeDispatchInfo; } else { - return (await this.api!.call.transactionPaymentApi.queryInfo(tx, len)) as RuntimeDispatchInfo; + return (await api.call.transactionPaymentApi.queryInfo(tx, len)) as RuntimeDispatchInfo; } } constructApiCall(apiCall: string, params: any[]) { + if(this.api === null) throw Error('API not initialized'); if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`); let call = this.getApi() as any; for(const part of apiCall.slice(4).split('.')) { @@ -2274,6 +2276,25 @@ async transferToSubstrate(signer: TSigner, address: TSubstrateAccount, amount: bigint | string): Promise { return this.subBalanceGroup.transferToSubstrate(signer, address, amount); } + + async forceTransferToSubstrate(signer: TSigner, from: TSubstrateAccount, to: TSubstrateAccount, amount: bigint | string): Promise { + const result = await this.helper.executeExtrinsic(signer, 'api.tx.balances.forceTransfer', [from, to, amount], true); + + let transfer = {from: null, to: null, amount: 0n} as any; + result.result.events.forEach(({event: {data, method, section}}) => { + if ((section === 'balances') && (method === 'Transfer')) { + transfer = { + from: this.helper.address.normalizeSubstrate(data[0]), + to: this.helper.address.normalizeSubstrate(data[1]), + amount: BigInt(data[2]), + }; + } + }); + let isSuccess = this.helper.address.normalizeSubstrate(from) === transfer.from; + isSuccess = isSuccess && this.helper.address.normalizeSubstrate(to) === transfer.to; + isSuccess = isSuccess && BigInt(amount) === transfer.amount; + return isSuccess; + } } class AddressGroup extends HelperGroup { @@ -2418,52 +2439,6 @@ } class SchedulerGroup extends HelperGroup { - scheduledIdSlider = 0; - - async waitNoScheduledTasks() { - const api = this.helper.api!; - - // eslint-disable-next-line no-async-promise-executor - const promise = new Promise(async resolve => { - const unsubscribe = await api.rpc.chain.subscribeNewHeads(async () => { - const areThereScheduledTasks = await api.query.scheduler.lookup.entries(); - - if(areThereScheduledTasks.length == 0) { - unsubscribe(); - resolve(); - } - }); - }); - - return promise; - } - - async makeScheduledIds(num: number): Promise { - await this.waitNoScheduledTasks(); - - function makeId(slider: number) { - const scheduledIdSize = 32; - const hexId = slider.toString(16); - const prefixSize = scheduledIdSize - hexId.length; - - const scheduledId = '0x' + '0'.repeat(prefixSize) + hexId; - - return scheduledId; - } - - const ids = []; - for (let i = 0; i < num; i++) { - ids.push(makeId(this.scheduledIdSlider)); - this.scheduledIdSlider += 1; - } - - return ids; - } - - async makeScheduledId(): Promise { - return (await this.makeScheduledIds(1))[0]; - } - async cancelScheduled(signer: TSigner, scheduledId: string) { return this.helper.executeExtrinsic( signer, @@ -2990,6 +2965,10 @@ getSudo() { return new UniqueBaseCollection(this.collectionId, this.helper.getSudo()); } + + getSudo() { + return new UniqueCollectionBase(this.collectionId, this.helper.getSudo()); + } } -- gitstuff