git.delta.rocks / unique-network / refs/commits / fcb2b324d1ba

difftreelog

feat add sudo/scheduler support to playgrounds, several minor additions

Daniel Shiposha2022-09-16parent: #b36ccba.patch.diff
in: master

2 files changed

modifiedtests/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;
 
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
534 }534 }
535535
536 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);
538539
539 // We need to sign the tx because540 // We need to sign the tx because
540 // unsigned transactions does not have an inclusion fee541 // unsigned transactions does not have an inclusion fee
541 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 });
547548
548 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 }
554555
555 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 }
2279
2280 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);
2282
2283 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}
22782299
2279class AddressGroup extends HelperGroup<ChainHelperBase> {2300class AddressGroup extends HelperGroup<ChainHelperBase> {
2418}2439}
24192440
2420class SchedulerGroup extends HelperGroup<UniqueHelper> {2441class SchedulerGroup extends HelperGroup<UniqueHelper> {
2421 scheduledIdSlider = 0;
2422
2423 async waitNoScheduledTasks() {
2424 const api = this.helper.api!;
2425
2426 // eslint-disable-next-line no-async-promise-executor
2427 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();
2430
2431 if(areThereScheduledTasks.length == 0) {
2432 unsubscribe();
2433 resolve();
2434 }
2435 });
2436 });
2437
2438 return promise;
2439 }
2440
2441 async makeScheduledIds(num: number): Promise<string[]> {
2442 await this.waitNoScheduledTasks();
2443
2444 function makeId(slider: number) {
2445 const scheduledIdSize = 32;
2446 const hexId = slider.toString(16);
2447 const prefixSize = scheduledIdSize - hexId.length;
2448
2449 const scheduledId = '0x' + '0'.repeat(prefixSize) + hexId;
2450
2451 return scheduledId;
2452 }
2453
2454 const ids = [];
2455 for (let i = 0; i < num; i++) {
2456 ids.push(makeId(this.scheduledIdSlider));
2457 this.scheduledIdSlider += 1;
2458 }
2459
2460 return ids;
2461 }
2462
2463 async makeScheduledId(): Promise<string> {
2464 return (await this.makeScheduledIds(1))[0];
2465 }
2466
2467 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 }
2968
2969 getSudo() {
2970 return new UniqueCollectionBase(this.collectionId, this.helper.getSudo());
2971 }
2993}2972}
29942973
29952974