git.delta.rocks / unique-network / refs/commits / 040a586ad19f

difftreelog

source

tests/src/transfer.nload.ts4.0 KiBsourcehistory
1import { ApiPromise } from "@polkadot/api";2import { IKeyringPair } from '@polkadot/types/types';3import privateKey from "./substrate/privateKey";4import usingApi, { submitTransactionAsync } from "./substrate/substrate-api";5import waitNewBlocks from "./substrate/wait-new-blocks";6import { findUnusedAddresses } from "./util/helpers";7import * as cluster from 'cluster';8import os from 'os';910// Innacurate transfer fee11const FEE = 10n ** 8n;1213let counters: { [key: string]: number } = {};14function increaseCounter(name: string, amount: number) {15    if (!counters[name]) {16        counters[name] = 0;17    }18    counters[name] += amount;19}20function flushCounterToMaster() {21    if (Object.keys(counters).length === 0) {22        return;23    }24    process.send!(counters);25    counters = {};26}2728async function distributeBalance(source: IKeyringPair, api: ApiPromise, totalAmount: bigint, stages: number) {29    let accounts = [source];30    // we don't need source in output array31    const failedAccounts = [0];3233    const finalUserAmount = 2 ** stages - 1;34    accounts.push(...await findUnusedAddresses(api, finalUserAmount));35    // findUnusedAddresses produces at least 1 request per user36    increaseCounter('requests', finalUserAmount);3738    for (let stage = 0; stage < stages; stage++) {39        let usersWithBalance = 2 ** stage;40        let amount = totalAmount / (2n ** BigInt(stage)) - FEE * BigInt(stage);41        // console.log(`Stage ${stage}/${stages}, ${usersWithBalance} => ${usersWithBalance * 2} = ${amount}`);42        let txs = [];43        for (let i = 0; i < usersWithBalance; i++) {44            let newUser = accounts[i + usersWithBalance];45            // console.log(`${accounts[i].address} => ${newUser.address} = ${amountToSplit}`);46            const tx = api.tx.balances.transfer(newUser.address, amount);47            txs.push(submitTransactionAsync(accounts[i], tx).catch(e => {48                failedAccounts.push(i + usersWithBalance);49                increaseCounter('txFailed', 1);50            }));51            increaseCounter('tx', 1);52        }53        await Promise.all(txs);54    }5556    for (let account of failedAccounts.reverse()) {57        accounts.splice(account, 1);58    }59    return accounts;60}6162if (cluster.isMaster) {63    let testDone = false;64    usingApi(async (api) => {65        let prevCounters: { [key: string]: number } = {};66        while (!testDone) {67            for (let name in counters) {68                if (!(name in prevCounters)) {69                    prevCounters[name] = 0;70                }71                if(counters[name] === prevCounters[name]) {72                    continue;73                }74                console.log(`${name.padEnd(15)} = ${counters[name] - prevCounters[name]}`);75                prevCounters[name] = counters[name];76            }77            await waitNewBlocks(api, 1);78        }79    });80    let waiting: Promise<void>[] = [];81    console.log(`Starting ${os.cpus().length} workers`);82    usingApi(async (api) => {83        const alice = privateKey('//Alice');84        for (let id in os.cpus()) {85            const WORKER_NAME = `//LoadWorker${id}_${Date.now()}`;86            const workerAccount = privateKey(WORKER_NAME);87            const tx = api.tx.balances.transfer(workerAccount.address, 400n * 10n ** 23n);88            await submitTransactionAsync(alice, tx);8990            let worker = cluster.fork({91                WORKER_NAME,92                STAGES: id + 293            });94            worker.on('message', msg => {95                for (let key in msg) {96                    increaseCounter(key, msg[key]);97                }98            });99            waiting.push(new Promise(res => worker.on('exit', res)));100        }101        await Promise.all(waiting);102        testDone = true;103    })104} else {105    increaseCounter('startedWorkers', 1);106    usingApi(async (api) => {107        await distributeBalance(privateKey(process.env.WORKER_NAME as string), api, 400n * 10n ** 22n, 10);108    });109    const interval = setInterval(() => {110        flushCounterToMaster();111    }, 100);112    interval.unref();113}