Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/vcounters 2 #321

Merged
merged 5 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ jobs:
run: |
export NUM_CPUS=31
npm run test:start
sh tools/checker.sh
sh tools/parallel-testing/checker.sh
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ stats.html
build

# testvectors files
tools/parallel-tests
tools/parallel-testing/parallel-tests
tools/parallel-testing/countersDiffs.csv


.vscode/launch.json
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@0xpolygonhermez/zkevm-rom",
"version": "3.0.0",
"version": "4.0.0",
"description": "zkROM source code",
"main": "index.js",
"scripts": {
Expand All @@ -21,8 +21,10 @@
"test:zkasm": "node tools/run-tests-zkasm.js ./test --helpers ../main/helper.js",
"eslint": "npx eslint tools/**.js && npx eslint counters/counters-executor.js",
"eslint:fix": "npx eslint tools/**.js --fix && npx eslint counters/counters-executor.js --fix",
"test:gen": "node tools/gen-parallel-tests.js",
"test:start": "npx mocha --jobs $NUM_CPUS --timeout 0 --max-old-space-size=8192 --parallel \"tools/parallel-tests/*.test.js\""
"test:gen": "node tools/parallel-testing/gen-parallel-tests.js",
"test:start": "npx mocha --jobs $NUM_CPUS --timeout 0 --max-old-space-size=8192 --parallel \"tools/parallel-testing/parallel-tests/*.test.js\"",
"report:free-inputs": "node tools/audit-tools/free-inputs-checker.js",
"report:registry-op": "node tools/audit-tools/registry-op-checker.js"
},
"keywords": [
"zkrom",
Expand All @@ -41,9 +43,9 @@
"yargs": "^17.5.1"
},
"devDependencies": {
"@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-rc.4-fork.7",
"@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-fork.7",
"@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#b1540abf1fd1306e5eb11817abe40145b27a48ae",
"@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v4.0.0-rc.4-fork.7",
"@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v4.0.0-fork.7",
"chai": "^4.3.6",
"chalk": "^3.0.0",
"eslint": "^8.25.0",
Expand Down
71 changes: 71 additions & 0 deletions tools/audit-tools/registry-op-checker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* eslint-disable no-use-before-define */
/* eslint-disable no-continue */
/* eslint-disable no-restricted-syntax */
const rom = require('../../build/rom.json');
const argv = require('yargs');

/**
* This script checks if there are new registry operations in the rom build. It compares it with the rom input selected
* The result is logged in the console.
*/
async function main() {
// load rom input
let input = {};

if (argv._.length === 0) {
console.log('You need to specify an input file');
process.exit(1);
} else if (argv._.length === 1) {
console.log('path input: ', argv._[0]);
input = JSON.parse(await fs.promises.readFile(argv._[0], 'utf8'));
} else {
console.log('Only one input file at a time is permitted');
process.exit(1);
}

// Find free inputs at rom's build
const regOpFound = getRegOpFromBuild(rom.program);
const prevRegOpFound = getRegOpFromBuild(input.program);
const diffFound = [];
// Compare found registers with previous rom
for (const op of regOpFound) {
const found = prevRegOpFound.find((item) => item.key === op.key);
if (!found) {
diffFound.push(op);
}
}
// Log warnings, f.e. a free input with more than one occurrence
for (const op of diffFound) {
console.log(`WARNING: Found new registry operation at ${op.fileName}:${op.line}->${op.lineStr}`);
}
console.log('FINISHED');
}

function getRegOpFromBuild(build) {
const regOpFound = [];
// Check all steps
for (const step of build) {
let count = 0;
// Get steps where we operate with registers
for (const key of Object.keys(step)) {
if (key === 'inA' || key === 'inB' || key === 'inC' || key === 'inD' || key === 'inE' || key === 'inF') {
if (step.lineStr.includes('*')) {
count += 1;
}
if (Object.keys(step).includes('CONST')) {
count += 1;
}
count += 1;
}
}
// Save steps with more than one register operation
if (count > 1) {
// Remove spaces from string
step.key = `${step.lineStr.replace(/\s/g, '')}-${step.fileName}`;
regOpFound.push(step);
}
}

return regOpFound;
}
main();
2 changes: 1 addition & 1 deletion tools/checker.sh → tools/parallel-testing/checker.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh
FILE=$PWD/tools/parallel-tests/checker.txt
FILE=$PWD/tools/parallel-testing/parallel-tests/checker.txt
if [ -f "$FILE" ]; then
cat "$FILE"
exit 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ const { compile } = require('pilcom');
const buildPoseidon = require('@0xpolygonhermez/zkevm-commonjs').getPoseidon;

const folderPaths = [
'../node_modules/@0xpolygonhermez/zkevm-testvectors/inputs-executor',
'../node_modules/@0xpolygonhermez/zkevm-testvectors/inputs-executor/ethereum-tests/GeneralStateTests',
'../../node_modules/@0xpolygonhermez/zkevm-testvectors/inputs-executor',
'../../node_modules/@0xpolygonhermez/zkevm-testvectors/inputs-executor/ethereum-tests/GeneralStateTests',
];

const fileCachePil = path.join(__dirname, '../node_modules/@0xpolygonhermez/zkevm-proverjs/cache-main-pil.json');
const pathMainPil = path.join(__dirname, '../node_modules/@0xpolygonhermez/zkevm-proverjs/pil/main.pil');
const fileCachePil = path.join(__dirname, '../../node_modules/@0xpolygonhermez/zkevm-proverjs/cache-main-pil.json');
const pathMainPil = path.join(__dirname, '../../node_modules/@0xpolygonhermez/zkevm-proverjs/pil/main.pil');
const inputs = [];
const testsFolder = path.join(__dirname, 'parallel-tests');
const sampleDir = path.join(__dirname, 'parallel-tests-sample/sample.test.js');
Expand Down Expand Up @@ -42,12 +42,12 @@ async function main() {
fs.readdirSync(inputsPath).forEach((file) => {
const filePath = path.join(inputsPath, file);
// Remove json lists that are generated with gen inputs script and are not inputs
if (file.endsWith('.json') && !file.includes('testsOOC-list.json') && !file.includes('tests30M-list.json')) {
if (file.endsWith('.json') && !file.includes('testsOOC-list.json') && !file.includes('tests30M-list.json') && !file.includes('no-exec')) {
inputs.push(filePath);
} else if (fs.statSync(filePath).isDirectory() && !filePath.includes('tests-OOC')) {
fs.readdirSync(filePath).forEach((subFile) => {
const subFilePath = path.join(filePath, subFile);
if (subFile.endsWith('.json') && !subFile.includes('testsOOC-list.json') && !subFile.includes('tests30M-list.json')) {
if (subFile.endsWith('.json') && !subFile.includes('testsOOC-list.json') && !subFile.includes('tests30M-list.json') && !subFile.includes('no-exec')) {
inputs.push(subFilePath);
}
});
Expand All @@ -66,6 +66,8 @@ async function main() {
const pil = await compile(F, pathMainPil, null, pilConfig);
fs.writeFileSync(fileCachePil, `${JSON.stringify(pil, null, 1)}\n`, 'utf8');
genTestsFiles();
// Generate counters diff table csv file
fs.writeFileSync(path.join(__dirname, 'countersDiffs.csv'), 'Test name,vSteps,rSteps,StepsDiff,vArith,rArith,ArithDiff,vBinary,rBinary,BinaryDiff,vMemAlign,rMemAlign,memAlignDiff,vKeccaks,rKeccaks,keccaksDiff,vPoseidon,rPoseidon,PoseidonDiff,vPadding,rPadding,PaddingDiff,vSHA256,rSHA256,SHA256Diff\n', 'utf8');
}

main();
133 changes: 133 additions & 0 deletions tools/parallel-testing/parallel-tests-sample/sample.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/* eslint-disable global-require */
/* eslint-disable import/no-dynamic-require */
/* eslint-disable no-use-before-define */
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable import/extensions */
/* eslint-disable import/no-unresolved */
const { expect } = require('chai');
const fs = require('fs');
const path = require('path');

const { newCommitPolsArray } = require('pilcom');
const smMain = require('@0xpolygonhermez/zkevm-proverjs/src/sm/sm_main/sm_main');

let rom = require('../../../build/rom.json');

let stepsN = 2 ** 23;
let counters = false;

const fileCachePil = path.join(__dirname, '../../../node_modules/@0xpolygonhermez/zkevm-proverjs/cache-main-pil.json');

const checkerDir = path.join(__dirname, 'checker.txt');

const inputPath = '%%INPUT_PATH%%';
const nameFile = path.basename(inputPath);
const input = JSON.parse(fs.readFileSync(inputPath, 'utf8'));

it(`${nameFile}`, async () => {
if (fs.existsSync(checkerDir)) {
process.exit(1);
}
const pil = JSON.parse(fs.readFileSync(fileCachePil));
const cmPols = newCommitPolsArray(pil);
if (input.gasLimit) {
rom = require(`../../../build/rom-${input.gasLimit}.test.json`);
}
if (input.stepsN) {
stepsN = input.stepsN;
counters = true;
}
await runTest(cmPols, stepsN);

expect(true).to.be.equal(true);
});

async function runTest(cmPols, steps) {
try {
const config = {
debug: true,
debugInfo: {
inputName: path.basename(inputPath),
},
stepsN: steps,
counters,
assertOutputs: true,
};

const res = await smMain.execute(cmPols.Main, input, rom, config);
compareCounters(input.virtualCounters, res.counters);
} catch (err) {
fs.writeFileSync(checkerDir, `Failed test ${inputPath} - ${err}}`);
throw err;
}
}

function compareCounters(virtualCounters, result) {
const countersDiff = {
steps: {
virtual: virtualCounters.steps,
real: Number(result.cntSteps),
diff: getPercentageDiff(virtualCounters.steps, Number(result.cntSteps)),
},
arith: {
virtual: virtualCounters.arith,
real: Number(result.cntArith),
diff: getPercentageDiff(virtualCounters.arith, Number(result.cntArith)),
},
binary: {
virtual: virtualCounters.binary,
real: Number(result.cntBinary),
diff: getPercentageDiff(virtualCounters.binary, Number(result.cntBinary)),
},
memAlign: {
virtual: virtualCounters.memAlign,
real: Number(result.cntMemAlign),
diff: getPercentageDiff(virtualCounters.memAlign, Number(result.cntMemAlign)),
},
keccaks: {
virtual: virtualCounters.keccaks,
real: Number(result.cntKeccakF),
diff: getPercentageDiff(virtualCounters.keccaks, Number(result.cntKeccakF)),
},
poseidon: {
virtual: virtualCounters.poseidon,
real: Number(result.cntPoseidonG),
diff: getPercentageDiff(virtualCounters.poseidon, Number(result.cntPoseidonG)),
},
padding: {
virtual: virtualCounters.padding,
real: Number(result.cntPaddingPG),
diff: getPercentageDiff(virtualCounters.padding, Number(result.cntPaddingPG)),
},
sha256: {
virtual: virtualCounters.sha256,
real: Number(result.cntSha256F),
diff: getPercentageDiff(virtualCounters.sha256, Number(result.cntSha256F)),
},
};
fs.appendFileSync(path.join(__dirname, '../countersDiffs.csv'), `${nameFile},${countersDiff.steps.virtual},${countersDiff.steps.real},${String(countersDiff.steps.diff).replace('.', ',')},${countersDiff.arith.virtual},${countersDiff.arith.real},${String(countersDiff.arith.diff).replace('.', ',')},${countersDiff.binary.virtual},${countersDiff.binary.real},${String(countersDiff.binary.diff).replace('.', ',')},${countersDiff.memAlign.virtual},${countersDiff.memAlign.real},${String(countersDiff.memAlign.diff).replace('.', ',')},${countersDiff.keccaks.virtual},${countersDiff.keccaks.real},${String(countersDiff.keccaks.diff).replace('.', ',')},${countersDiff.poseidon.virtual},${countersDiff.poseidon.real},${String(countersDiff.poseidon.diff).replace('.', ',')},${countersDiff.padding.virtual},${countersDiff.padding.real},${String(countersDiff.padding.diff).replace('.', ',')},${countersDiff.sha256.virtual},${countersDiff.sha256.real},${String(countersDiff.sha256.diff).replace('.', ',')}\n`);
// Check percentages are greater than 0
Object.keys(countersDiff).forEach((key) => {
if (Number(countersDiff[key].diff) < 0) {
throw new Error(`Negative percentage diff: ${countersDiff[key].virtual}/${countersDiff[key].real}/${countersDiff[key].diff}% at ${key}}`);
}
});
}

function getPercentageDiff(a, b) {
if (a === 0) {
// a and b are 0
if (b === 0) {
return 0;
}
// a is 0 but b is not -> fail test

return -100;
}
// a is not 0 but b is -> passed
if (b === 0) {
return 0;
}

return (((a - b) / b) * 100).toFixed(2);
}
62 changes: 0 additions & 62 deletions tools/parallel-tests-sample/sample.test.js

This file was deleted.

Loading