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

feat: add node task #1378

Closed
wants to merge 5 commits into from
Closed
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
67 changes: 64 additions & 3 deletions packages/hardhat-zksync-node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { spawn } from 'child_process';
import { task, subtask, types } from 'hardhat/config';
import {
TASK_COMPILE,
TASK_NODE,
TASK_TEST,
TASK_TEST_GET_TEST_FILES,
TASK_TEST_RUN_MOCHA_TESTS,
} from 'hardhat/builtin-tasks/task-names';

import { HARDHAT_NETWORK_NAME } from 'hardhat/plugins';
import { TaskArguments } from 'hardhat/types';
import {
MAX_PORT_ATTEMPTS,
START_PORT,
Expand All @@ -16,7 +18,7 @@ import {
TASK_NODE_ZKSYNC_DOWNLOAD_BINARY,
TASK_RUN_NODE_ZKSYNC_IN_SEPARATE_PROCESS,
} from './constants';
import { JsonRpcServer } from './server';
import { JsonRpcServer, RpcServer } from './server';
import {
adjustTaskArgsForPort,
configureNetwork,
Expand Down Expand Up @@ -75,9 +77,68 @@ subtask(TASK_NODE_ZKSYNC_CREATE_SERVER, 'Creates a JSON-RPC server for ZKsync no
},
);

task(TASK_NODE, 'Start a ZKSync Node')
.addOptionalParam('log', 'Log filter level (error, warn, info, debug) - default: info', undefined, types.string)
.addOptionalParam(
'logFilePath',
'Path to the file where logs should be written - default: `era_test_node.log`',
undefined,
types.string,
)
.addOptionalParam('cache', 'Cache type (none, disk, memory) - default: disk', undefined, types.string)
.addOptionalParam(
'cacheDir',
'Cache directory location for `disk` cache - default: `.cache`',
undefined,
types.string,
)
.addFlag('resetCache', 'Reset the local `disk` cache')
.addOptionalParam(
'showCalls',
'Show call debug information (none, user, system, all) - default: none',
undefined,
types.string,
)
.addOptionalParam(
'showStorageLogs',
'Show storage log information (none, read, write, all) - default: none',
undefined,
types.string,
)
.addOptionalParam(
'showVmDetails',
'Show VM details information (none, all) - default: none',
undefined,
types.string,
)
.addOptionalParam(
'showGasDetails',
'Show Gas details information (none, all) - default: none',
undefined,
types.string,
)
.addFlag(
'resolveHashes',
'Try to contact openchain to resolve the ABI & topic names. It enabled, it makes debug log more readable, but will decrease the performance',
)
.addFlag(
'devUseLocalContracts',
'Loads the locally compiled system contracts (useful when doing changes to system contracts or bootloader)',
)
.addOptionalParam('replayTx', 'Transaction hash to replay', undefined, types.string)
.addOptionalParam('tag', 'Specified node release for use', undefined)
// .addOptionalParam('force', 'Force download', undefined, types.boolean)
.setAction(async (args: TaskArguments, { network, run }, runSuper) => {
if (network.zksync !== true || network.name !== HARDHAT_NETWORK_NAME) {
return await runSuper();
}

await run(TASK_NODE_ZKSYNC, args);
});

// Main task of the plugin. It starts the server and listens for requests.
task(TASK_NODE_ZKSYNC, 'Starts a JSON-RPC server for ZKsync node')
.addOptionalParam('port', 'Port to listen on - default: 8011', undefined, types.int)
.addOptionalParam('port', 'Port to listen on - default: 8545', 8545, types.int)
.addOptionalParam('log', 'Log filter level (error, warn, info, debug) - default: info', undefined, types.string)
.addOptionalParam(
'logFilePath',
Expand Down Expand Up @@ -196,7 +257,7 @@ task(TASK_NODE_ZKSYNC, 'Starts a JSON-RPC server for ZKsync node')
const binaryPath: string = await run(TASK_NODE_ZKSYNC_DOWNLOAD_BINARY, { force: false, tag });

// Create the server
const server: JsonRpcServer = await run(TASK_NODE_ZKSYNC_CREATE_SERVER, { binaryPath });
const server: RpcServer = await run(TASK_NODE_ZKSYNC_CREATE_SERVER, { binaryPath });

try {
await server.listen(commandArgs);
Expand Down
7 changes: 6 additions & 1 deletion packages/hardhat-zksync-node/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import chalk from 'chalk';

import { PROCESS_TERMINATION_SIGNALS } from './constants';

export class JsonRpcServer {
export interface RpcServer {
listen(args?: string[], blockProcess?: boolean): Promise<void>;
stop(): Promise<void>;
}

export class JsonRpcServer implements RpcServer {
private serverProcess: ChildProcess | null = null;

// eslint-disable-next-line @typescript-eslint/naming-convention
Expand Down
26 changes: 26 additions & 0 deletions packages/hardhat-zksync-node/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ import {
ALLOWED_SHOW_STORAGE_LOGS_VALUES,
ALLOWED_SHOW_VM_DETAILS_VALUES,
BASE_URL,
MAX_PORT_ATTEMPTS,
NETWORK_ACCOUNTS,
NETWORK_ETH,
NETWORK_GAS,
NETWORK_GAS_PRICE,
PLATFORM_MAP,
START_PORT,
TEMP_FILE_PREFIX,
ZKSYNC_ERA_TEST_NODE_NETWORK_NAME,
} from './constants';
import { ZkSyncNodePluginError } from './errors';
import { CommandArguments } from './types';
import { RPCServerDownloader } from './downloader';
import { JsonRpcServer } from './server';

// Generates command arguments for running the era-test-node binary
export function constructCommandArgs(args: CommandArguments): string[] {
Expand Down Expand Up @@ -406,3 +410,25 @@ export async function configureNetwork(config: HardhatConfig, network: any, port
config.networks[network.name] = network.config;
network.provider = await createProvider(config, network.name);
}

export const startServer = async (tag?: string, force: boolean = false) => {
const platform = getPlatform();
if (platform === 'windows' || platform === '') {
throw new ZkSyncNodePluginError(`Unsupported platform: ${platform}`);
}
const rpcServerBinaryDir = await getRPCServerBinariesDir();

const downloader: RPCServerDownloader = new RPCServerDownloader(rpcServerBinaryDir, tag || 'latest');

await downloader.downloadIfNeeded(force);
const binaryPath = await downloader.getBinaryPath();

const currentPort = await getAvailablePort(START_PORT, MAX_PORT_ATTEMPTS);
const commandArgs = constructCommandArgs({ port: currentPort });

return {
commandArgs,
server: new JsonRpcServer(binaryPath),
port: currentPort,
};
};
Loading