Skip to content

Commit

Permalink
feat: support an option to fallback to optimizing for size solc (#660)
Browse files Browse the repository at this point in the history
* feat: support an option to fallback to optimizing for size

* chore: add tests and use semver

* refactor: lint compile tests

---------

Co-authored-by: Marko Arambasic <makiarambasic@gmail.com>
kiriyaga-txfusion and kiriyaga authored Jan 25, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 163deaa commit eaf4413
Showing 12 changed files with 75 additions and 25 deletions.
6 changes: 4 additions & 2 deletions packages/hardhat-zksync-solc/src/compile/binary.ts
Original file line number Diff line number Diff line change
@@ -7,11 +7,13 @@ export async function compileWithBinary(
solcPath: string,
detectMissingLibrariesMode: boolean = false,
): Promise<any> {
const { compilerPath, isSystem, forceEvmla } = config.settings;
const { compilerPath, isSystem, forceEvmla, fallbackOz } = config.settings;

const processCommand = `${compilerPath} --standard-json ${isSystem ? '--system-mode' : ''} ${
forceEvmla ? '--force-evmla' : ''
} --solc ${solcPath} ${detectMissingLibrariesMode ? '--detect-missing-libraries' : ''}`;
} ${fallbackOz ? '--fallback-Oz' : ''} --solc ${solcPath} ${
detectMissingLibrariesMode ? '--detect-missing-libraries' : ''
}`;

const output: string = await new Promise((resolve, reject) => {
const process = exec(
3 changes: 3 additions & 0 deletions packages/hardhat-zksync-solc/src/compile/docker.ts
Original file line number Diff line number Diff line change
@@ -128,6 +128,9 @@ export async function compileWithDocker(
if (zksolcConfig.settings.forceEvmla) {
command.push('--force-evmla');
}
if (zksolcConfig.settings.fallbackOz) {
command.push('--fallback-Oz');
}

// @ts-ignore
const dockerInstance: Docker = docker._docker;
13 changes: 12 additions & 1 deletion packages/hardhat-zksync-solc/src/compile/index.ts
Original file line number Diff line number Diff line change
@@ -4,7 +4,10 @@ import { CompilerInput } from 'hardhat/types';
import { ZkSolcConfig } from '../types';
import { ZkSyncSolcPluginError } from '../errors';
import { findMissingLibraries, mapMissingLibraryDependencies, writeLibrariesToFile } from '../utils';
import { DETECT_MISSING_LIBRARY_MODE_COMPILER_VERSION } from '../constants';
import {
DETECT_MISSING_LIBRARY_MODE_COMPILER_VERSION,
ZKSOLC_COMPILER_MIN_VERSION_WITH_FALLBACK_OZ,
} from '../constants';
import {
validateDockerIsInstalled,
createDocker,
@@ -17,6 +20,14 @@ import { compileWithBinary } from './binary';

export async function compile(zksolcConfig: ZkSolcConfig, input: CompilerInput, solcPath?: string) {
let compiler: ICompiler;
if (
zksolcConfig.settings.fallbackOz &&
semver.lt(zksolcConfig.version, ZKSOLC_COMPILER_MIN_VERSION_WITH_FALLBACK_OZ)
) {
throw new ZkSyncSolcPluginError(
`FallbackOz option is not supported for zksolc compiler version ${zksolcConfig.version}. Please use version ${ZKSOLC_COMPILER_MIN_VERSION_WITH_FALLBACK_OZ} or higher.`,
);
}
if (zksolcConfig.compilerSource === 'binary') {
if (solcPath === null) {
throw new ZkSyncSolcPluginError('solc executable is not specified');
2 changes: 1 addition & 1 deletion packages/hardhat-zksync-solc/src/constants.ts
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ export const ZKSOLC_COMPILERS_SELECTOR_MAP = {
'1.3.5': ['abi', 'evm.methodIdentifiers', 'storageLayout', 'irOptimized', 'evm.legacyAssembly', 'ast'],
};
/* eslint-enable @typescript-eslint/naming-convention */

export const ZKSOLC_COMPILER_MIN_VERSION_WITH_FALLBACK_OZ = '1.3.21';
export const ZKSOLC_COMPILER_VERSION_MIN_VERSION = '1.3.13';
export const ZKSOLC_BIN_OWNER = 'matter-labs';
export const ZKSOLC_BIN_REPOSITORY_NAME = 'zksolc-bin';
2 changes: 2 additions & 0 deletions packages/hardhat-zksync-solc/src/types.ts
Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@ export interface ZkSolcConfig {
enabled?: boolean;
[key: string]: any;
};
// Try to recompile with -Oz if the bytecode is too large.
fallbackOz?: boolean;
// Remove metadata hash from bytecode. If the option is ommited, the metadata hash will be appended by default.
metadata?: {
bytecodeHash?: 'none';
Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.

This file was deleted.

66 changes: 53 additions & 13 deletions packages/hardhat-zksync-solc/test/tests/compile/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { expect } from 'chai';
import { CompilerInput } from 'hardhat/types';
import path from 'path';
import sinon from 'sinon';
import { compile } from '../../../src/compile';
import { ZkSolcConfig } from '../../../src/types';
import * as binary from '../../../src/compile/binary';

describe('compile', () => {
const sandbox = sinon.createSandbox();

let compileStub: sinon.SinonStub;

const input: CompilerInput = {
language: 'Solidity',
sources: {
@@ -26,28 +31,26 @@ describe('compile', () => {
},
};

it.skip('should compile with binary compiler', async () => {
let zksolcPath;
let solcPath;
beforeEach(async () => {
compileStub = sandbox.stub(binary, 'compileWithBinary').resolves({ output: {}, errors: {} });
});

if (process.platform) {
zksolcPath = path.resolve('./test/compiler-files/linux/zksolc');
solcPath = path.resolve('./test/compiler-files/linux/solc');
} else {
zksolcPath = path.resolve('./test/compiler-files/macos/zksolc');
solcPath = path.resolve('./test/compiler-files/macos/solc');
}
afterEach(() => {
sandbox.restore();
});

it('should compile with binary compiler', async () => {
const zksolcConfig: ZkSolcConfig = {
compilerSource: 'binary',
version: '1.3.17',
settings: {
compilerPath: zksolcPath,
compilerPath: 'path/to/zksolc',
},
};

const result = await compile(zksolcConfig, input, solcPath);
const result = await compile(zksolcConfig, input, 'path/to/solc');

compileStub.calledOnceWith(input, zksolcConfig, 'path/to/solc');
expect(result).to.be.an('object');
expect(result).to.have.property('errors');
});
@@ -66,6 +69,7 @@ describe('compile', () => {

const result = await compile(zksolcConfig, input);

compileStub.calledOnceWith(input, zksolcConfig, 'path/to/solc');
expect(result).to.be.an('object');
expect(result).to.have.property('errors');
});
@@ -87,4 +91,40 @@ describe('compile', () => {
expect(error.message).to.equal('Incorrect compiler source: undefined');
}
});

it('should throw an error for unsupported zksolc compiler version with fallbackOz', async () => {
const zksolcConfig: ZkSolcConfig = {
compilerSource: 'binary',
version: '1.3.16',
settings: {
fallbackOz: true,
},
};

try {
await compile(zksolcConfig, input, 'path/to/solc');
// If the function does not throw an error, fail the test
expect.fail('Expected ZkSyncSolcPluginError to be thrown');
} catch (error: any) {
expect(error.message).to.equal(
'FallbackOz option is not supported for zksolc compiler version 1.3.16. Please use version 1.3.21 or higher.',
);
}
});

it('should zksolc compiler compile with fallbackOz', async () => {
const zksolcConfig: ZkSolcConfig = {
compilerSource: 'binary',
version: '1.3.21',
settings: {
fallbackOz: true,
},
};

const result = await compile(zksolcConfig, input, 'path/to/solc');

compileStub.calledOnceWith(input, zksolcConfig, 'path/to/solc');
expect(result).to.be.an('object');
expect(result).to.have.property('errors');
});
});

0 comments on commit eaf4413

Please sign in to comment.