Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Better tests for keccak precompile #58

Merged
merged 8 commits into from Nov 21, 2023
38 changes: 35 additions & 3 deletions test/Keccak256.spec.ts
@@ -1,10 +1,15 @@
import { CONTRACT_DEPLOYER_ADDRESS, hashBytecode } from 'zksync-web3/build/src/utils';
import { KeccakTest, KeccakTest__factory } from '../typechain-types';
import { KECCAK256_CONTRACT_ADDRESS } from './shared/constants';
import { getCode, getWallets, loadArtifact, publishBytecode, setCode } from './shared/utils';
import { getWallets, loadArtifact, publishBytecode, setCode } from './shared/utils';
import { ethers } from 'hardhat';
import { readYulBytecode } from '../scripts/utils';
import { Language } from '../scripts/constants';
import { Wallet } from 'ethers';
import { expect } from 'chai';

describe('Keccak256 tests', function () {
let testWallet: Wallet;
let keccakTest: KeccakTest;

let correctKeccakCodeHash: string;
Expand All @@ -14,15 +19,21 @@ describe('Keccak256 tests', function () {
const KECCAK_TEST_ADDRESS = '0x0000000000000000000000000000000000009000';

before(async () => {
testWallet = getWallets()[0];

await setCode(
KECCAK_TEST_ADDRESS,
(await loadArtifact('KeccakTest')).bytecode
);

keccakTest = KeccakTest__factory.connect(KECCAK_TEST_ADDRESS, getWallets()[0]);
const correctKeccakCode = await getCode(KECCAK256_CONTRACT_ADDRESS);
const correctKeccakCode = readYulBytecode({
codeName: 'Keccak256',
path: 'precompiles',
lang: Language.Yul,
address: ethers.constants.AddressZero
});

// The test node might use outdated contracts
const correctContractDeployerCode = (await loadArtifact('ContractDeployer')).bytecode;
await setCode(CONTRACT_DEPLOYER_ADDRESS, correctContractDeployerCode);

Expand All @@ -39,6 +50,27 @@ describe('Keccak256 tests', function () {
await keccakTest.zeroPointerTest()
});

it('general functionality test', async () => {
// We currently do not have fussing support, so we generate random data using
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that it is non-trivial to integrate Echidna or other Fuzz tooling at the moment. But this test seems to me weird. data is always 32 bytes long. I would rather make a couple of randomly generated tests:

  • 0 bytes long
  • x * BLOCK_SIZE - 2
  • x * BLOCK_SIZE - 1
  • x * BLOCK_SIZE
  • x * BLOCK_SIZE + 1
  • x * BLOCK_SIZE + 2

It is to cover all possible variants of branching

// hash function.

const seed = ethers.utils.randomBytes(32);
// Displaying seed for reproducible tests
console.log('Keccak256 fussing seed', ethers.utils.hexlify(seed));

for(let i = 0; i < 5; i++) {
const data = ethers.utils.keccak256(ethers.utils.hexConcat([seed, i]));

const correctHash = ethers.utils.keccak256(data);
const hashFromPrecompile = await testWallet.provider.call({
to: KECCAK256_CONTRACT_ADDRESS,
data: data
});

expect(hashFromPrecompile).to.equal(correctHash, 'Hash is incorrect');
}
});

it('keccak upgrade test', async() => {
const deployerInterfact = new ethers.utils.Interface((await loadArtifact('ContractDeployer')).abi);

Expand Down