diff --git a/solidity/.gitignore b/solidity/.gitignore index 75fd174..4990488 100644 --- a/solidity/.gitignore +++ b/solidity/.gitignore @@ -6,4 +6,5 @@ typechain-types ignition/deployments .openzeppelin package-lock.json -**/*.csv \ No newline at end of file +**/*costs.csv +**/*_plot.png \ No newline at end of file diff --git a/solidity/test/gas_cost/plot.ipynb b/solidity/test/gas_cost/plot.ipynb new file mode 100644 index 0000000..f6ff2bb --- /dev/null +++ b/solidity/test/gas_cost/plot.ipynb @@ -0,0 +1,89 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import os\n", + "\n", + "\n", + "folder_path = './' # update with the actual folder path if using this notebook in a different place\n", + "prefix = '2024-09-23T05:02:36.434Z' # update with specific file prefix that needs to be plotted\n", + "\n", + "window_size = 500 # how many transaction to measure to draw the moving average trend line\n", + "threshold_tx = 5000 # highlight area after how many transactions\n", + "\n", + "# find a list of CSV files in the folder with the specified prefix\n", + "csv_files = [f for f in os.listdir(folder_path) if f.startswith(prefix) and f.endswith('.csv')]\n", + "\n", + "figures = []\n", + "\n", + "for csv_file in csv_files:\n", + " # read the gas costs from the file\n", + " file_path = os.path.join(folder_path, csv_file)\n", + " df = pd.read_csv(file_path)\n", + " gas_costs = df['gas_costs'].tolist()\n", + "\n", + " # generate transactions index\n", + " transactions = np.arange(1, len(gas_costs) + 1)\n", + " df['transactions'] = transactions\n", + "\n", + " # calculates the moving average within the defined window\n", + " df['moving_avg'] = df['gas_costs'].rolling(window=window_size).mean()\n", + "\n", + "\n", + " # plot the data\n", + " plt.figure(figsize=(10, 6))\n", + " plt.plot(df['transactions'], df['gas_costs'], label=\"Gas Costs\", color='lightblue', marker='o')\n", + " plt.plot(df['transactions'], df['moving_avg'], label=f\"{window_size}-TX Moving Average\", color='orange', linewidth=2)\n", + "\n", + " # create highlight\n", + " plt.axvline(x=threshold_tx, color='darkred', linestyle='--', label=f'{threshold_tx} transactions')\n", + " plt.fill_between(df['transactions'], df['gas_costs'], where=(df['transactions'] > threshold_tx), color='pink', alpha=0.5)\n", + "\n", + " plt.xlabel('Number of Transactions')\n", + " plt.ylabel('Gas Cost')\n", + " plt.title(f'Gas Costs and {window_size}-Transaction Moving Average for {csv_file}')\n", + " plt.legend()\n", + "\n", + " # saving the plots as images\n", + " output_file = os.path.join(folder_path, f\"{csv_file.replace('.csv', '')}_plot.png\")\n", + " plt.savefig(output_file)\n", + "\n", + " # also store them in the array to display inline\n", + " figures.append(plt.gcf()) \n", + "\n", + "# display all plots\n", + "for fig in figures:\n", + " plt.figure(fig.number)\n", + " plt.show()\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/solidity/test/gas_cost/zeto_anon_enc_nullifier_kyc_cost_analysis.ts b/solidity/test/gas_cost/zeto_anon_enc_nullifier_kyc_cost_analysis.ts index 8422737..a8ffced 100644 --- a/solidity/test/gas_cost/zeto_anon_enc_nullifier_kyc_cost_analysis.ts +++ b/solidity/test/gas_cost/zeto_anon_enc_nullifier_kyc_cost_analysis.ts @@ -42,8 +42,8 @@ import { } from '../utils'; import { deployZeto } from '../lib/deploy'; -const TOTAL_AMOUNT = parseInt(process.env.TOTAL_ROUNDS || '4'); -const TX_CONCURRENCY = parseInt(process.env.TX_CONCURRENCY || '20'); +const TOTAL_AMOUNT = parseInt(process.env.TOTAL_ROUNDS || '1000'); +const TX_CONCURRENCY = parseInt(process.env.TX_CONCURRENCY || '30'); describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity using nullifiers and encryption with KYC', function () { let deployer: Signer; @@ -115,28 +115,6 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin // console.log(`Deposit costs: ${depositGasCostHistory.join(',')}`); // console.log(`Transfer costs: ${transferGasCostHistory.join(',')}`); // console.log(`Withdraw costs: ${withdrawGasCostHistory.join(',')}`); - - writeGasCostsToCSV( - `${reportPrefix}mint_gas_costs.csv`, - mintGasCostHistory, - 'Mint Gas Costs' - ); - writeGasCostsToCSV( - `${reportPrefix}deposit_gas_costs.csv`, - depositGasCostHistory, - 'Deposit Gas Costs' - ); - writeGasCostsToCSV( - `${reportPrefix}transfer_gas_costs.csv`, - transferGasCostHistory, - 'Transfer Gas Costs' - ); - - writeGasCostsToCSV( - `${reportPrefix}withdraw_gas_costs.csv`, - withdrawGasCostHistory, - 'Withdraw Gas Costs' - ); }); describe(`Transfer ${TOTAL_AMOUNT} tokens (half from deposit, half from mint) from single address to another`, function () { @@ -205,6 +183,10 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin if (promises.length > 0) { await Promise.all(promises); } + writeGasCostsToCSV( + `${reportPrefix}deposit_gas_costs.csv`, + depositGasCostHistory + ); }).timeout(6000000000000); it(`Zeto mint ${atMostHalfAmount + (TOTAL_AMOUNT % 2)} token to Alice in ${ @@ -255,6 +237,10 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin if (promises.length > 0) { await Promise.all(promises); } + writeGasCostsToCSV( + `${reportPrefix}mint_gas_costs.csv`, + mintGasCostHistory + ); }).timeout(6000000000000); it(`Alice transfer ${TOTAL_AMOUNT} tokens to Bob in ${atLeastHalfAmount} txs`, async function () { @@ -338,6 +324,10 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin if (promises.length > 0) { await Promise.all(promises); } + writeGasCostsToCSV( + `${reportPrefix}transfer_gas_costs.csv`, + transferGasCostHistory + ); }).timeout(6000000000000); it(`Bob withdraw ${TOTAL_AMOUNT} tokens`, async function () { @@ -382,6 +372,10 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin ); } } + writeGasCostsToCSV( + `${reportPrefix}withdraw_gas_costs.csv`, + withdrawGasCostHistory + ); // Bob checks ERC20 balance const endingBalance = await erc20.balanceOf(Bob.ethAddress); expect(endingBalance - startingBalance).to.be.equal(TOTAL_AMOUNT); @@ -551,19 +545,14 @@ describe.skip('(Gas cost analysis) Zeto based fungible token with anonymity usin } }); -function writeGasCostsToCSV( - filename: string, - gasCosts: number[], - header: string -) { +function writeGasCostsToCSV(filename: string, gasCosts: number[]) { const filePath = path.join(__dirname, filename); // Prepare the CSV content - const csvHeader = `${header}\n`; const csvData = gasCosts.join(',\n') + '\n'; // Each value in a new line // Write the CSV content to a file (overwrite if file exists) - fs.writeFileSync(filePath, csvHeader + csvData, 'utf8'); + fs.writeFileSync(filePath, 'gas_costs,\n' + csvData, 'utf8'); console.log(`Gas costs written to ${filePath}`); }