-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #266 from 0xPolygonHermez/develop
Develop
- Loading branch information
Showing
91 changed files
with
3,287 additions
and
1,162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,3 +72,4 @@ build | |
|
||
# testvectors files | ||
tools/parallel-tests | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
## Counters testing tool | ||
|
||
The purpose of this tool is to detect counters altertions in zkrom code. | ||
A unit test is created for each function and opcode of the zkEVM. The structure of the test is the following: | ||
````` | ||
INCLUDE "../initIncludes.zkasm" // Include the files imported at the beginning of the test | ||
start: | ||
1000000 => GAS | ||
operation: | ||
2 :MSTORE(SP++) | ||
2 :MSTORE(SP++) | ||
:JMP(opADD) | ||
// Assert counters. Check for each function, the exact number of each counter is matched | ||
checkCounters: | ||
%OPADD_STEP - STEP:JMPN(failedCounters) | ||
%OPADD_CNT_BINARY - CNT_BINARY :JMPNZ(failedCounters) | ||
%OPADD_CNT_ARITH - CNT_ARITH :JMPNZ(failedCounters) | ||
%OPADD_CNT_KECCAK_F - CNT_KECCAK_F :JMPNZ(failedCounters) | ||
%OPADD_CNT_MEM_ALIGN - CNT_MEM_ALIGN :JMPNZ(failedCounters) | ||
%OPADD_CNT_PADDING_PG - CNT_PADDING_PG :JMPNZ(failedCounters) | ||
%OPADD_CNT_POSEIDON_G - CNT_POSEIDON_G :JMPNZ(failedCounters) | ||
// Finalize execution | ||
0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, HASHPOS, RR ; Set all registers to 0 | ||
finalizeExecution: | ||
:JMP(finalWait) | ||
readCode: | ||
txType: | ||
:JMP(checkCounters) | ||
failedCounters: // Force failed assert | ||
2 => A | ||
1 :ASSERT | ||
INCLUDE "../endIncludes.zkasm" // Include the files imported at the end of the test | ||
````` | ||
|
||
Run all tests: | ||
````` | ||
node counters/counters-executor.js | ||
````` | ||
Limitations: | ||
- Not all the tests are implemented yet, just the most complex ones | ||
- For some test (the simplest ones), the counters it should spend are stored in `countersConstants.zkasm` file. For tests with a lot of utils calls or a lot of complexity, the values of the counters are hardcoded in the test. | ||
- The tests always try to cover as much coverage as posible and always with the worst case counters scenario but this approach gets a bit tricky for complex opcodes as they have different contexts and behaviours. | ||
- The objective is to keep adding tests with already not implemented functions but also adding tests for already implemented opcodes but with different scenarios (Example: calldatacopy from a call or from a create2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
const smMain = require('@0xpolygonhermez/zkevm-proverjs/src/sm/sm_main/sm_main'); | ||
const fileCachePil = path.join(__dirname, '../node_modules/@0xpolygonhermez/zkevm-proverjs/cache-main-pil.json'); | ||
const empty_input = require('@0xpolygonhermez/zkevm-proverjs/test/inputs/empty_input.json') | ||
const buildPoseidon = require('@0xpolygonhermez/zkevm-commonjs').getPoseidon; | ||
const pathMainPil = path.join(__dirname, '../node_modules/@0xpolygonhermez/zkevm-proverjs/pil/main.pil'); | ||
const { newCommitPolsArray } = require('pilcom'); | ||
const { compile } = require('pilcom'); | ||
const zkasm = require("@0xpolygonhermez/zkasmcom"); | ||
const testFilesDir = path.join(__dirname, './tests'); | ||
const { argv } = require('yargs'); | ||
|
||
async function main() { | ||
|
||
// Compile pil | ||
const cmPols = await compilePil(); | ||
|
||
// Get all zkasm files | ||
const files = getTestFiles(); | ||
|
||
// Run all zkasm files | ||
for (let file of files) { | ||
await runTest(file, cmPols) | ||
} | ||
} | ||
|
||
async function runTest(testName, cmPols) { | ||
const zkasmFile = `${testFilesDir}/${testName}`; | ||
// Compile rom | ||
const configZkasm = { | ||
defines: [], | ||
allowUndefinedLabels: true | ||
}; | ||
|
||
const rom = await zkasm.compile(zkasmFile, null, configZkasm); | ||
const config = { | ||
debug: true, | ||
stepsN: 8388608, | ||
} | ||
console.log(`Running ${testName}`) | ||
// Execute test | ||
const res = await smMain.execute(cmPols.Main, empty_input, rom, config); | ||
console.log(res.counters) | ||
} | ||
|
||
// Get all zkasm counter test files | ||
function getTestFiles() { | ||
if(argv.test){ | ||
return [`${argv.test}.zkasm`] | ||
} | ||
const files = fs.readdirSync(testFilesDir).filter(name => name.endsWith('.zkasm')) | ||
return files | ||
} | ||
|
||
async function compilePil() { | ||
if (!fs.existsSync(fileCachePil)) { | ||
const poseidon = await buildPoseidon(); | ||
const { F } = poseidon; | ||
const pilConfig = { | ||
defines: { N: 4096 }, | ||
namespaces: ['Main', 'Global'], | ||
disableUnusedError: true | ||
}; | ||
const p = await compile(F, pathMainPil, null, pilConfig); | ||
fs.writeFileSync(fileCachePil, `${JSON.stringify(p, null, 1)}\n`, 'utf8'); | ||
} | ||
|
||
const pil = JSON.parse(fs.readFileSync(fileCachePil)); | ||
return newCommitPolsArray(pil); | ||
} | ||
|
||
main() |
Oops, something went wrong.