1import {usingPlaygrounds} from '../util';2345const WS_ENDPOINT = 'ws://localhost:9944';6const DONOR_SEED = '//Alice';78export const main = async(options: { wsEndpoint: string; donorSeed: string } = {9 wsEndpoint: WS_ENDPOINT,10 donorSeed: DONOR_SEED,11}) => {12 await usingPlaygrounds(async (helper, privateKey) => {13 const api = helper.getApi();1415 if((await api.query.maintenance.enabled()).valueOf()) {16 throw Error('The network is still in maintenance mode');17 }1819 const pendingBlocks = (20 await api.query.appPromotion.pendingUnstake.entries()21 ).map(([k, _v]) =>22 k.args[0]);2324 const currentBlock = await api.query.system.number();2526 const filteredBlocks = pendingBlocks.filter((b) => currentBlock.gt(b));2728 if(filteredBlocks.length != 0) {29 console.log(30 'During maintenance mode, %d block(s) were not processed',31 filteredBlocks.length,32 );33 } else {34 console.log('Nothing to change');35 return;36 }3738 const skippedBlocks = chunk(filteredBlocks, 10);3940 const signer = await privateKey(options.donorSeed);4142 const txs = skippedBlocks.map((b) =>43 api.tx.sudo.sudo(api.tx.appPromotion.forceUnstake(b)));444546 const promises = txs.map((tx) => () => helper.signTransaction(signer, tx));4748 await Promise.allSettled(promises.map((p) => p()));4950 const failedBlocks: bigint[] = [];51 let isSuccess = true;5253 for(const b of filteredBlocks) {54 if(((await api.query.appPromotion.pendingUnstake(b)).toJSON() as any[]).length != 0) {55 failedBlocks.push(b.toBigInt());56 isSuccess = false;57 }58 }5960 if(isSuccess) {61 console.log('Done. %d block(s) were processed.', filteredBlocks.length);62 } else {63 throw new Error(`Something went wrong. Block(s) have not been processed: ${failedBlocks}`);64 }656667 }, options.wsEndpoint);68};6970const chunk = <T>(arr: T[], size: number) =>71 Array.from({length: Math.ceil(arr.length / size)}, (_: any, i: number) =>72 arr.slice(i * size, i * size + size));