From 361e77e4873f16ce443d641fef42dfa704661097 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 14 Sep 2022 18:11:32 +0200 Subject: [PATCH] npm run net-search-performance-plateau https://github.com/DMDcoin/honey-badger-testing/issues/41 --- package.json | 3 +- src/net/runSearchPerformancePlateau.ts | 114 +++++++++++++++++++++++++ src/tools/awaitTransactions.ts | 33 +++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/net/runSearchPerformancePlateau.ts create mode 100644 src/tools/awaitTransactions.ts diff --git a/package.json b/package.json index aa6f47b..3431e71 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "net-send-dummy-txs": "ts-node src/runContinousTransactionsSender.ts", "net-add-validator-each-epoch": "ts-node src/regression/runAddOneValidatorEachEpoch.ts", "net-register-names": "ts-node src/net/runRegisterNames.ts", + "net-search-performance-plateau": "ts-node src/net/runSearchPerformancePlateau.ts", "localnet-blockscout-fresh": "cd testnet/blockscout-local && docker-compose down && docker-compose up", "testnet-start-current": "ts-node src/runWatchdog.ts --boot", "testnet-watchdog": "ts-node src/runWatchdog.ts", @@ -78,7 +79,7 @@ "testnet-print-state": "ts-node src/regression/runPrintTestnetState.ts", "testnet-clear-validator-dbs": "ts-node src/regression/runClearValidatorsDB.ts", "testnet-fresh-grow-each-epoch": "npm-run-all testnet-fresh addOneValidatorEachEpoch", - "testnet-fresh": "export STAKING_TRANSITION_WINDOW_LENGTH=120 && export STAKING_EPOCH_DURATION=240 && export MINIMUM_BLOCK_TIME=1 && cd testnet && ./setup_testnet.py 5 5 && cd -", + "testnet-fresh": "export STAKING_TRANSITION_WINDOW_LENGTH=120 && export STAKING_EPOCH_DURATION=240 && export MINIMUM_BLOCK_TIME=1 && cd testnet && ./setup_testnet.py 4 4 && cd -", "testnet-fresh-12hour": "export STAKING_TRANSITION_WINDOW_LENGTH=600 && export STAKING_EPOCH_DURATION=43200 && export MINIMUM_BLOCK_TIME=1 && export MAXIMUM_BLOCK_TIME=600 && cd testnet && ./setup_testnet.py 25 25 && cd -", "testnet-test-availability-handling-current": "ts-node src/regression/testAvailabilityHandling.ts", "testnet-test-availability-handling-fresh": "export STAKING_TRANSITION_WINDOW_LENGTH=90 && export STAKING_EPOCH_DURATION=120 && export MINIMUM_BLOCK_TIME=1 && export NETWORK_ID=666001 && cd testnet && ./setup_testnet.py 1 17 && cd - && export NODE_ENV=localhost && npm run testnet-test-availability-handling-current", diff --git a/src/net/runSearchPerformancePlateau.ts b/src/net/runSearchPerformancePlateau.ts new file mode 100644 index 0000000..d71181a --- /dev/null +++ b/src/net/runSearchPerformancePlateau.ts @@ -0,0 +1,114 @@ +import { object } from "underscore"; +import { ConfigManager } from "../configManager"; +import { ContractManager } from "../contractManager"; +import { sleep } from "../utils/time"; +import fs from "fs"; +import { awaitTransactions } from "../tools/awaitTransactions"; + + +function toNumber(value: string | number) : number { + if (typeof value === "number") { + return value; + } + + if (typeof value === "string") { + return Number.parseInt(value); + } + + throw Error('not a number'); + +} + +async function run() { + + const config = ConfigManager.getConfig(); + const contractManager = ContractManager.get(); + const web3 = contractManager.web3; + + const wallets = ConfigManager.insertWallets(web3, 50); + + const defaultGasPrice = '1000000000000'; + console.log("Warmup: Funding Accounts."); + + let confirmed = 0; + let feedAccount = web3.eth.defaultAccount!; + let nonceFeed = await web3.eth.getTransactionCount(feedAccount); + for(const wallet of wallets) { + web3.eth.sendTransaction({ from: feedAccount, to: wallet.address, nonce: nonceFeed, value: web3.utils.toWei('1', "ether"), gas: "21000", gasPrice: defaultGasPrice}) + .once("receipt", () => { + confirmed++ + }); + nonceFeed++; + } + + console.log('waiting for Accounts to be funded.'); + + while ( confirmed < wallets.length) { + console.log(`confirmed ${confirmed}/${wallets.length}`); + await sleep(1000); + } + + console.log('funds transfers confirmed.'); + console.log('Ramping up - finding plateu'); + + let txPerAccount = 1; + let outputFile = 'find-plateau.csv'; + console.log(`writing output to ${outputFile}`); + fs.writeFileSync(outputFile, "tx-per-account;num-of-accounts;total-txs;number-of-blocks;sum-of-block-time;blockStart;blockEnd;block-per-second;txs-per-second;\n"); + + + // make a transaction to ensure the start of block production on hbbft. + web3.eth.sendTransaction({ from: web3.eth.defaultAccount!, to: web3.eth.defaultAccount!, nonce: nonceFeed, value: web3.utils.toWei('1', "ether"), gas: "21000", gasPrice: defaultGasPrice}); + + while (txPerAccount < 10) { // this while condition is kind of a max - we early exit if we have found a plateau. + + const blockStart = await web3.eth.getBlockNumber(); + const blockStartInstance = await web3.eth.getBlock(blockStart); + const blockStartTime = toNumber(blockStartInstance.timestamp); + + let totalTxs = txPerAccount * wallets.length; + let transactionHashesToConfirm : Array = []; + for(const wallet of wallets) { + + let nonce = await web3.eth.getTransactionCount(wallet.address); + + for(let i = 0; i { + transactionHashesToConfirm.push(transactionHash); + }); + nonce++; + } + } + + console.log(`transactions Sent: ${transactionHashesToConfirm.length} scanning blocks to verify transaction receipts...`); + + + + const blockEnd = await awaitTransactions(web3, blockStart, transactionHashesToConfirm); + console.log(`all transactions confirmed with block:`, blockEnd); + + const blockEndInstance = await web3.eth.getBlock(blockEnd); + const numOfBlocks = blockEnd - blockStart; + const blockEndTime = toNumber(blockEndInstance.timestamp); + const sumOfBlockTime = blockEndTime - blockStartTime; + const blocksPerSecond = numOfBlocks / sumOfBlockTime; + const txsPerSecond = totalTxs / sumOfBlockTime; + + fs.appendFileSync(outputFile, `${txPerAccount};${wallets.length};${totalTxs};${numOfBlocks};${sumOfBlockTime};${blockStart};${blockEnd};${blocksPerSecond.toPrecision(4)};${txsPerSecond.toPrecision(4)};\n`); + txPerAccount++; + } + + + + + console.log('transactions funded.'); + + + + + + +} + +run(); \ No newline at end of file diff --git a/src/tools/awaitTransactions.ts b/src/tools/awaitTransactions.ts new file mode 100644 index 0000000..5376ef5 --- /dev/null +++ b/src/tools/awaitTransactions.ts @@ -0,0 +1,33 @@ +import Web3 from "web3"; +import { sleep } from "../utils/time"; + + + +export async function awaitTransactions(web3: Web3, blockBeforeTxSend: number, transactions: Array) : Promise { + + let lastAnalysedBlock = blockBeforeTxSend; + + while ( transactions.length > 0 ) { + await sleep(200); + // console.log("awaiting confirmation of txs: ", transactions.length); + let currentBlock = await web3.eth.getBlockNumber(); + + for (let blockToAnalyse = lastAnalysedBlock; blockToAnalyse < currentBlock; blockToAnalyse ++) { + console.log('analysing block', blockToAnalyse); + + const block = await web3.eth.getBlock(blockToAnalyse); + + const txCountBeforeFilter = transactions.length; + transactions = transactions.filter(x => !block.transactions.includes(x)); + const txCountAfterFilter = transactions.length; + const txCountConfirmed = txCountBeforeFilter - txCountAfterFilter; + console.log(`block ${blockToAnalyse} proccessed. confirmed txs: ${txCountConfirmed}`); + } + + lastAnalysedBlock = currentBlock; + } + + console.log('all transactions confirmed at block:', lastAnalysedBlock); + + return lastAnalysedBlock; +} \ No newline at end of file