Skip to content

Commit

Permalink
Merge branch 'main' into aon-add-zk-toolbox
Browse files Browse the repository at this point in the history
  • Loading branch information
aon authored May 17, 2024
2 parents 9f200ab + 3300047 commit 41ad6b3
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 78 deletions.
26 changes: 17 additions & 9 deletions core/tests/ts-integration/scripts/compile-yul.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@ export function spawn(command: string) {
});
}

export async function compile(path: string, files: string[], outputDirName: string | null, type: string) {
export async function compile(
pathToHome: string,
path: string,
files: string[],
outputDirName: string | null,
type: string
) {
if (!files.length) {
console.log(`No test files provided in folder ${path}.`);
return;
}
let paths = preparePaths(path, files, outputDirName);
let paths = preparePaths(pathToHome, path, files, outputDirName);

let systemMode = type === 'yul' ? '--system-mode --optimization 3' : '';

Expand All @@ -50,23 +56,23 @@ export async function compile(path: string, files: string[], outputDirName: stri
);
}

export async function compileFolder(path: string, type: string) {
export async function compileFolder(pathToHome: string, path: string, type: string) {
let files: string[] = (await fs.promises.readdir(path)).filter((fn) => fn.endsWith(`.${type}`));
for (const file of files) {
await compile(path, [file], `${file}`, type);
await compile(pathToHome, path, [file], `${file}`, type);
}
}

function preparePaths(path: string, files: string[], outputDirName: string | null): CompilerPaths {
function preparePaths(pathToHome: string, path: string, files: string[], outputDirName: string | null): CompilerPaths {
const filePaths = files
.map((val, _) => {
return `sources/${val}`;
})
.join(' ');
const outputDir = outputDirName || files[0];
let absolutePathSources = `${process.env.ZKSYNC_HOME}/core/tests/ts-integration/${path}`;
let absolutePathSources = `${pathToHome}/core/tests/ts-integration/${path}`;

let absolutePathArtifacts = `${process.env.ZKSYNC_HOME}/core/tests/ts-integration/${path}/artifacts`;
let absolutePathArtifacts = `${pathToHome}/core/tests/ts-integration/${path}/artifacts`;

return new CompilerPaths(filePaths, outputDir, absolutePathSources, absolutePathArtifacts);
}
Expand All @@ -76,6 +82,7 @@ class CompilerPaths {
public outputDir: string;
public absolutePathSources: string;
public absolutePathArtifacts: string;

constructor(filePath: string, outputDir: string, absolutePathSources: string, absolutePathArtifacts: string) {
this.filePath = filePath;
this.outputDir = outputDir;
Expand All @@ -85,8 +92,9 @@ class CompilerPaths {
}

async function main() {
await compileFolder('contracts/yul', 'yul');
await compileFolder('contracts/zkasm', 'zkasm');
const pathToHome = path.join(__dirname, '../../../../');
await compileFolder(pathToHome, 'contracts/yul', 'yul');
await compileFolder(pathToHome, 'contracts/zkasm', 'zkasm');
}

main()
Expand Down
6 changes: 3 additions & 3 deletions core/tests/ts-integration/src/context-owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class TestContextOwner {
this.reporter.startAction(`Cancelling allowances transactions`);
// Since some tx may be pending on stage, we don't want to get stuck because of it.
// In order to not get stuck transactions, we manually cancel all the pending txs.
const chainId = process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!;
const chainId = this.env.l2ChainId;

const bridgehub = await this.mainSyncWallet.getBridgehubContract();
const erc20Bridge = await bridgehub.sharedBridge();
Expand Down Expand Up @@ -275,7 +275,7 @@ export class TestContextOwner {
) {
this.reporter.startAction(`Distributing base tokens on L1`);
if (baseTokenAddress != zksync.utils.ETH_ADDRESS_IN_CONTRACTS) {
const chainId = process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!;
const chainId = this.env.l2ChainId;
const l1startNonce = await this.mainEthersWallet.getTransactionCount();
this.reporter.debug(`Start nonce is ${l1startNonce}`);
const ethIsBaseToken =
Expand Down Expand Up @@ -365,7 +365,7 @@ export class TestContextOwner {
l2erc20DepositAmount: ethers.BigNumber,
baseTokenAddress: zksync.types.Address
) {
const chainId = process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!;
const chainId = this.env.l2ChainId;
this.reporter.startAction(`Distributing tokens on L1`);
const l1startNonce = await this.mainEthersWallet.getTransactionCount();
this.reporter.debug(`Start nonce is ${l1startNonce}`);
Expand Down
40 changes: 36 additions & 4 deletions core/tests/ts-integration/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as path from 'path';
import * as fs from 'fs';
import * as ethers from 'ethers';
import * as zksync from 'zksync-ethers';
import { TestEnvironment } from './types';
import { DataAvailabityMode, NodeMode, TestEnvironment } from './types';
import { Reporter } from './reporter';
import { L2_BASE_TOKEN_ADDRESS } from 'zksync-ethers/build/utils';

Expand Down Expand Up @@ -76,7 +76,8 @@ export async function loadTestEnvironment(): Promise<TestEnvironment> {
? process.env.CONTRACT_VERIFIER_URL!
: ensureVariable(process.env.CONTRACT_VERIFIER_URL, 'Contract verification API');

const tokens = getTokens(process.env.CHAIN_ETH_NETWORK || 'localhost');
const pathToHome = path.join(__dirname, '../../../../');
const tokens = getTokens(pathToHome, process.env.CHAIN_ETH_NETWORK || 'localhost');
// wBTC is chosen because it has decimals different from ETH (8 instead of 18).
// Using this token will help us to detect decimals-related errors.
// but if it's not available, we'll use the first token from the list.
Expand All @@ -103,8 +104,39 @@ export async function loadTestEnvironment(): Promise<TestEnvironment> {
).l2TokenAddress(weth.address);

const baseTokenAddressL2 = L2_BASE_TOKEN_ADDRESS;
const l2ChainId = parseInt(process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!);
const l1BatchCommitDataGeneratorMode = process.env
.CHAIN_STATE_KEEPER_L1_BATCH_COMMIT_DATA_GENERATOR_MODE! as DataAvailabityMode;
let minimalL2GasPrice;
if (process.env.CHAIN_STATE_KEEPER_MINIMAL_L2_GAS_PRICE !== undefined) {
minimalL2GasPrice = ethers.BigNumber.from(process.env.CHAIN_STATE_KEEPER_MINIMAL_L2_GAS_PRICE!);
} else {
minimalL2GasPrice = ethers.BigNumber.from(0);
}
let nodeMode;
if (process.env.EN_MAIN_NODE_URL !== undefined) {
nodeMode = NodeMode.External;
} else {
nodeMode = NodeMode.Main;
}

const validationComputationalGasLimit = parseInt(
process.env.CHAIN_STATE_KEEPER_VALIDATION_COMPUTATIONAL_GAS_LIMIT!
);
const priorityTxMaxGasLimit = parseInt(process.env.CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT!);
const maxLogsLimit = parseInt(
process.env.EN_REQ_ENTITIES_LIMIT ?? process.env.API_WEB3_JSON_RPC_REQ_ENTITIES_LIMIT!
);

return {
maxLogsLimit,
pathToHome,
priorityTxMaxGasLimit,
validationComputationalGasLimit,
nodeMode,
minimalL2GasPrice,
l1BatchCommitDataGeneratorMode,
l2ChainId,
network,
mainWalletPK,
l2NodeUrl,
Expand Down Expand Up @@ -152,8 +184,8 @@ type L1Token = {
address: string;
};

function getTokens(network: string): L1Token[] {
const configPath = `${process.env.ZKSYNC_HOME}/etc/tokens/${network}.json`;
function getTokens(pathToHome: string, network: string): L1Token[] {
const configPath = `${pathToHome}/etc/tokens/${network}.json`;
if (!fs.existsSync(configPath)) {
return [];
}
Expand Down
3 changes: 2 additions & 1 deletion core/tests/ts-integration/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function getTestContract(name: string): ZkSyncArtifact {
* @returns Conta
*/
export function getContractSource(relativePath: string): string {
const contractPath = `${process.env.ZKSYNC_HOME}/core/tests/ts-integration/contracts/${relativePath}`;
const contractPath = `${__dirname}/../contracts/${relativePath}`;
const source = fs.readFileSync(contractPath, 'utf8');
return source;
}
Expand Down Expand Up @@ -77,6 +77,7 @@ export async function waitForNewL1Batch(wallet: zksync.Wallet): Promise<zksync.t
}
return await wallet.provider.getTransactionReceipt(oldReceipt.transactionHash);
}

/**
* Waits until the requested block is finalized.
*
Expand Down
42 changes: 42 additions & 0 deletions core/tests/ts-integration/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { ethers } from 'ethers';

export enum NodeMode {
Main,
External
}

export enum DataAvailabityMode {
Rollup = 'Rollup',
Validium = 'Validium'
}

/**
* Description of an ERC20 token.
*/
Expand All @@ -15,6 +25,38 @@ export interface Token {
* Description of the environment the integration tests are being run in.
*/
export interface TestEnvironment {
/*
* Max Logs limit
*/
maxLogsLimit: number;
/*
* Gas limit for priority txs
*/
priorityTxMaxGasLimit: number;
/*
* Gas limit for computations
*/
validationComputationalGasLimit: number;
/*
* Minimal gas price of l2
*/
minimalL2GasPrice: ethers.BigNumber;
/*
* Data availability mode
*/
l1BatchCommitDataGeneratorMode: DataAvailabityMode;
/*
* Path to code home directory
*/
pathToHome: string;
/**
* Chain Id of the L2 Network
*/
l2ChainId: number;
/*
* Mode of the l2 node
*/
nodeMode: NodeMode;
/**
* Plaintext name of the L1 network name (i.e. `localhost` or `goerli`).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fetch from 'node-fetch';
import fs from 'fs';
import { deployContract, getContractSource, getTestContract } from '../../src/helpers';
import { sleep } from 'zksync-ethers/build/utils';
import { NodeMode } from '../../src/types';

// Regular expression to match ISO dates.
const DATE_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{6})?/;
Expand Down Expand Up @@ -44,7 +45,7 @@ describe('Tests for the contract verification API', () => {
testMaster = TestMaster.getInstance(__filename);
alice = testMaster.mainAccount();

if (process.env.ZKSYNC_ENV!.startsWith('ext-node')) {
if (testMaster.environment().nodeMode == NodeMode.External) {
console.warn("You are trying to run contract verification tests on external node. It's not supported.");
}
});
Expand Down Expand Up @@ -72,7 +73,7 @@ describe('Tests for the contract verification API', () => {
let artifact = contracts.counter;
// TODO: use plugin compilation when it's ready instead of pre-compiled bytecode.
artifact.bytecode = fs.readFileSync(
`${process.env.ZKSYNC_HOME}/core/tests/ts-integration/contracts/counter/zkVM_bytecode.txt`,
`${testMaster.environment().pathToHome}/core/tests/ts-integration/contracts/counter/zkVM_bytecode.txt`,
'utf8'
);

Expand Down Expand Up @@ -136,10 +137,14 @@ describe('Tests for the contract verification API', () => {
});

test('should test yul contract verification', async () => {
const contractPath = `${process.env.ZKSYNC_HOME}/core/tests/ts-integration/contracts/yul/Empty.yul`;
const contractPath = `${
testMaster.environment().pathToHome
}/core/tests/ts-integration/contracts/yul/Empty.yul`;
const sourceCode = fs.readFileSync(contractPath, 'utf8');

const bytecodePath = `${process.env.ZKSYNC_HOME}/core/tests/ts-integration/contracts/yul/artifacts/Empty.yul/Empty.yul.zbin`;
const bytecodePath = `${
testMaster.environment().pathToHome
}/core/tests/ts-integration/contracts/yul/artifacts/Empty.yul/Empty.yul.zbin`;
const bytecode = fs.readFileSync(bytecodePath);

const contractFactory = new zksync.ContractFactory([], bytecode, alice);
Expand Down
4 changes: 3 additions & 1 deletion core/tests/ts-integration/tests/api/debug.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ describe('Debug methods', () => {
});

test('Should not fail for infinity recursion', async () => {
const bytecodePath = `${process.env.ZKSYNC_HOME}/core/tests/ts-integration/contracts/zkasm/artifacts/deep_stak.zkasm/deep_stak.zkasm.zbin`;
const bytecodePath = `${
testMaster.environment().pathToHome
}/core/tests/ts-integration/contracts/zkasm/artifacts/deep_stak.zkasm/deep_stak.zkasm.zbin`;
const bytecode = fs.readFileSync(bytecodePath);

const contractFactory = new zksync.ContractFactory([], bytecode, testMaster.mainAccount());
Expand Down
28 changes: 14 additions & 14 deletions core/tests/ts-integration/tests/api/web3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import * as zksync from 'zksync-ethers';
import { types } from 'zksync-ethers';
import { BigNumberish, ethers, Event } from 'ethers';
import { serialize } from '@ethersproject/transactions';
import { deployContract, getTestContract, waitForNewL1Batch, anyTransaction } from '../../src/helpers';
import { anyTransaction, deployContract, getTestContract, waitForNewL1Batch } from '../../src/helpers';
import { shouldOnlyTakeFee } from '../../src/modifiers/balance-checker';
import fetch, { RequestInit } from 'node-fetch';
import { EIP712_TX_TYPE, PRIORITY_OPERATION_L2_TX_TYPE } from 'zksync-ethers/build/utils';
import { NodeMode } from '../../src/types';

// Regular expression to match variable-length hex number.
const HEX_VALUE_REGEX = /^0x[\da-fA-F]*$/;
Expand All @@ -30,7 +31,7 @@ describe('web3 API compatibility tests', () => {
testMaster = TestMaster.getInstance(__filename);
alice = testMaster.mainAccount();
l2Token = testMaster.environment().erc20Token.l2Address;
chainId = process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!;
chainId = testMaster.environment().l2ChainId;
});

test('Should test block/transaction web3 methods', async () => {
Expand Down Expand Up @@ -110,7 +111,7 @@ describe('web3 API compatibility tests', () => {
// zks_getAllAccountBalances
// NOTE: `getAllBalances` will not work on external node,
// since TokenListFetcher is not running
if (!process.env.EN_MAIN_NODE_URL) {
if (testMaster.environment().nodeMode === NodeMode.Main) {
const balances = await alice.getAllBalances();
const tokenBalance = await alice.getBalance(l2Token);
expect(balances[l2Token.toLowerCase()].eq(tokenBalance));
Expand Down Expand Up @@ -197,7 +198,7 @@ describe('web3 API compatibility tests', () => {
const tx1 = await alice.provider.getTransaction(tx.transactionHash);
expect(tx1.l1BatchNumber).toEqual(expect.anything()); // Can be anything except `null` or `undefined`.
expect(tx1.l1BatchTxIndex).toEqual(expect.anything()); // Can be anything except `null` or `undefined`.
expect(tx1.chainId).toEqual(+process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!);
expect(tx1.chainId).toEqual(testMaster.environment().l2ChainId);
expect(tx1.type).toEqual(EIP1559_TX_TYPE);

expect(receipt.l1BatchNumber).toEqual(expect.anything()); // Can be anything except `null` or `undefined`.
Expand All @@ -211,7 +212,7 @@ describe('web3 API compatibility tests', () => {
blockWithTransactions.transactions.forEach((txInBlock, _) => {
expect(txInBlock.l1BatchNumber).toEqual(expect.anything()); // Can be anything except `null` or `undefined`.
expect(txInBlock.l1BatchTxIndex).toEqual(expect.anything()); // Can be anything except `null` or `undefined`.
expect(txInBlock.chainId).toEqual(+process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!);
expect(txInBlock.chainId).toEqual(testMaster.environment().l2ChainId);
expect([0, EIP712_TX_TYPE, PRIORITY_OPERATION_L2_TX_TYPE, EIP1559_TX_TYPE]).toContain(txInBlock.type);
});
});
Expand Down Expand Up @@ -242,7 +243,7 @@ describe('web3 API compatibility tests', () => {
});

test('Should test getFilterChanges for pending transactions', async () => {
if (process.env.EN_MAIN_NODE_URL) {
if (testMaster.environment().nodeMode === NodeMode.External) {
// Pending transactions logic doesn't work on EN since we don't have a proper mempool -
// transactions only appear in the DB after they are included in the block.
return;
Expand Down Expand Up @@ -606,7 +607,7 @@ describe('web3 API compatibility tests', () => {

test('Should check metamask interoperability', async () => {
// Prepare "metamask" wallet.
const from = new MockMetamask(alice);
const from = new MockMetamask(alice, testMaster.environment().l2ChainId);
const to = alice.address;
const web3Provider = new zksync.Web3Provider(from);
const signer = zksync.Signer.from(web3Provider.getSigner(), alice.provider);
Expand Down Expand Up @@ -649,9 +650,7 @@ describe('web3 API compatibility tests', () => {

test('Should check API returns error when there are too many logs in eth_getLogs', async () => {
const contract = await deployContract(alice, contracts.events, []);
const maxLogsLimit = parseInt(
process.env.EN_REQ_ENTITIES_LIMIT ?? process.env.API_WEB3_JSON_RPC_REQ_ENTITIES_LIMIT!
);
const maxLogsLimit = testMaster.environment().maxLogsLimit;

// Send 3 transactions that emit `maxLogsLimit / 2` events.
const tx1 = await contract.emitManyEvents(maxLogsLimit / 2);
Expand Down Expand Up @@ -854,7 +853,7 @@ describe('web3 API compatibility tests', () => {
});

test('Should check transaction signature', async () => {
const CHAIN_ID = +process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!;
const CHAIN_ID = testMaster.environment().l2ChainId;
const value = 1;
const gasLimit = 350000;
const gasPrice = await alice.provider.getGasPrice();
Expand Down Expand Up @@ -951,10 +950,11 @@ describe('web3 API compatibility tests', () => {

export class MockMetamask {
readonly isMetaMask: boolean = true;
readonly networkVersion = parseInt(process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!, 10);
readonly chainId: string = ethers.utils.hexlify(parseInt(process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!, 10));
readonly chainId: string;

constructor(readonly wallet: zksync.Wallet) {}
constructor(readonly wallet: zksync.Wallet, readonly networkVersion: number) {
this.chainId = ethers.utils.hexlify(networkVersion);
}

// EIP-1193
async request(req: { method: string; params?: any[] }) {
Expand Down
Loading

0 comments on commit 41ad6b3

Please sign in to comment.