difftreelog
feat add sudo/scheduler support to playgrounds, several minor additions
in: master
2 files changed
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- 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<string[]> {
+ 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<string> {
+ return (await this.makeScheduledIds(1))[0];
+ }
+
+ async captureEvents(eventSection: string, eventMethod: string): Promise<EventCapture> {
+ 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<void>(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<EventRecord | null>(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;
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth534 }534 }535535536 async getPaymentInfo(signer: TSigner, tx: any, len: number | null) {536 async getPaymentInfo(signer: TSigner, tx: any, len: number | null) {537 const api = this.getApi();537 const signingInfo = await this.api!.derive.tx.signingInfo(signer.address);538 const signingInfo = await api.derive.tx.signingInfo(signer.address);538539539 // We need to sign the tx because540 // We need to sign the tx because540 // unsigned transactions does not have an inclusion fee541 // unsigned transactions does not have an inclusion fee541 tx.sign(signer, {542 tx.sign(signer, {542 blockHash: this.api!.genesisHash,543 blockHash: api.genesisHash,543 genesisHash: this.api!.genesisHash,544 genesisHash: api.genesisHash,544 runtimeVersion: this.api!.runtimeVersion,545 runtimeVersion: api.runtimeVersion,545 nonce: signingInfo.nonce,546 nonce: signingInfo.nonce,546 });547 });547548548 if (len === null) {549 if (len === null) {549 return (await this.callRpc('api.rpc.payment.queryInfo', [tx.toHex()])) as RuntimeDispatchInfo;550 return (await this.callRpc('api.rpc.payment.queryInfo', [tx.toHex()])) as RuntimeDispatchInfo;550 } else {551 } else {551 return (await this.api!.call.transactionPaymentApi.queryInfo(tx, len)) as RuntimeDispatchInfo;552 return (await api.call.transactionPaymentApi.queryInfo(tx, len)) as RuntimeDispatchInfo;552 }553 }553 }554 }554555555 constructApiCall(apiCall: string, params: any[]) {556 constructApiCall(apiCall: string, params: any[]) {557 if(this.api === null) throw Error('API not initialized');556 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);558 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);557 let call = this.getApi() as any;559 let call = this.getApi() as any;558 for(const part of apiCall.slice(4).split('.')) {560 for(const part of apiCall.slice(4).split('.')) {2275 return this.subBalanceGroup.transferToSubstrate(signer, address, amount);2277 return this.subBalanceGroup.transferToSubstrate(signer, address, amount);2276 }2278 }22792280 async forceTransferToSubstrate(signer: TSigner, from: TSubstrateAccount, to: TSubstrateAccount, amount: bigint | string): Promise<boolean> {2281 const result = await this.helper.executeExtrinsic(signer, 'api.tx.balances.forceTransfer', [from, to, amount], true);22822283 let transfer = {from: null, to: null, amount: 0n} as any;2284 result.result.events.forEach(({event: {data, method, section}}) => {2285 if ((section === 'balances') && (method === 'Transfer')) {2286 transfer = {2287 from: this.helper.address.normalizeSubstrate(data[0]),2288 to: this.helper.address.normalizeSubstrate(data[1]),2289 amount: BigInt(data[2]),2290 };2291 }2292 });2293 let isSuccess = this.helper.address.normalizeSubstrate(from) === transfer.from;2294 isSuccess = isSuccess && this.helper.address.normalizeSubstrate(to) === transfer.to;2295 isSuccess = isSuccess && BigInt(amount) === transfer.amount;2296 return isSuccess;2297 }2277}2298}227822992279class AddressGroup extends HelperGroup<ChainHelperBase> {2300class AddressGroup extends HelperGroup<ChainHelperBase> {2418}2439}241924402420class SchedulerGroup extends HelperGroup<UniqueHelper> {2441class SchedulerGroup extends HelperGroup<UniqueHelper> {2421 scheduledIdSlider = 0;24222423 async waitNoScheduledTasks() {2424 const api = this.helper.api!;2425 2426 // eslint-disable-next-line no-async-promise-executor2427 const promise = new Promise<void>(async resolve => {2428 const unsubscribe = await api.rpc.chain.subscribeNewHeads(async () => {2429 const areThereScheduledTasks = await api.query.scheduler.lookup.entries();24302431 if(areThereScheduledTasks.length == 0) {2432 unsubscribe();2433 resolve();2434 }2435 }); 2436 });24372438 return promise;2439 }24402441 async makeScheduledIds(num: number): Promise<string[]> {2442 await this.waitNoScheduledTasks();24432444 function makeId(slider: number) {2445 const scheduledIdSize = 32;2446 const hexId = slider.toString(16);2447 const prefixSize = scheduledIdSize - hexId.length;24482449 const scheduledId = '0x' + '0'.repeat(prefixSize) + hexId;24502451 return scheduledId; 2452 }24532454 const ids = [];2455 for (let i = 0; i < num; i++) {2456 ids.push(makeId(this.scheduledIdSlider));2457 this.scheduledIdSlider += 1;2458 }24592460 return ids;2461 }24622463 async makeScheduledId(): Promise<string> {2464 return (await this.makeScheduledIds(1))[0];2465 }24662467 async cancelScheduled(signer: TSigner, scheduledId: string) {2442 async cancelScheduled(signer: TSigner, scheduledId: string) {2468 return this.helper.executeExtrinsic(2443 return this.helper.executeExtrinsic(2991 return new UniqueBaseCollection(this.collectionId, this.helper.getSudo<T>());2966 return new UniqueBaseCollection(this.collectionId, this.helper.getSudo<T>());2992 }2967 }29682969 getSudo() {2970 return new UniqueCollectionBase(this.collectionId, this.helper.getSudo());2971 }2993}2972}2994297329952974