From 8af9d498fa6c36d6cb238899b1110b3d6de80b2f Mon Sep 17 00:00:00 2001 From: mm Date: Mon, 6 May 2024 14:27:01 +0200 Subject: [PATCH 1/4] example of joining hyperchain --- .dockerignore | 1 + docker/local-node/Dockerfile | 2 + docker/local-node/entrypoint_slave.sh | 113 ++++++++++++++++++ .../local-setup-preparation/package.json | 3 +- .../src/join_hyperchain.ts | 86 +++++++++++++ 5 files changed, 204 insertions(+), 1 deletion(-) create mode 100755 docker/local-node/entrypoint_slave.sh create mode 100644 infrastructure/local-setup-preparation/src/join_hyperchain.ts diff --git a/.dockerignore b/.dockerignore index 603386e55e3b..98dc6e35e0b3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,7 @@ * !docker/prover/prover-entry.sh !docker/local-node/entrypoint.sh +!docker/local-node/entrypoint_slave.sh !docker/external-node/entrypoint.sh !docker/contract-verifier/install-all-solc.sh !etc/test_config diff --git a/docker/local-node/Dockerfile b/docker/local-node/Dockerfile index be74002a29b7..46a0c6106349 100644 --- a/docker/local-node/Dockerfile +++ b/docker/local-node/Dockerfile @@ -70,4 +70,6 @@ RUN mkdir /etc/env/l1-inits && mkdir /etc/env/l2-inits # setup entrypoint script COPY ./docker/local-node/entrypoint.sh /usr/bin/ +COPY ./docker/local-node/entrypoint_slave.sh /usr/bin/ + ENTRYPOINT ["entrypoint.sh"] diff --git a/docker/local-node/entrypoint_slave.sh b/docker/local-node/entrypoint_slave.sh new file mode 100755 index 000000000000..338d42fc5150 --- /dev/null +++ b/docker/local-node/entrypoint_slave.sh @@ -0,0 +1,113 @@ +#!/bin/bash +set -ea + +# These 3 env variables must be provided. +if [ -z "$DATABASE_URL" ]; then + echo "ERROR: DATABASE_URL is not set." + exit 1 +fi + +if [ -z "$DATABASE_PROVER_URL" ]; then + echo "ERROR: DATABASE_PROVER_URL is not set." + exit 1 +fi + +if [ -z "$ETH_CLIENT_WEB3_URL" ]; then + echo "ERROR: ETH_CLIENT_WEB3_URL is not set." + exit 1 +fi + +# Updates the value in the .toml config. +update_config() { + # Assigning arguments to readable variable names + local file="$1" + local parameter="$2" + local new_value="$3" + local pattern="^${parameter} =.*$" + + # Check if the parameter exists in the file + if grep -q "$pattern" "$file"; then + # The parameter exists, so replace its value + sed -i "s!$pattern!${parameter} =\"${new_value}\"!" "$file" + echo "Update successful for $parameter in $file." + else + # The parameter does not exist in the file, output error message and return non-zero status + echo "Error: '$parameter' not found in $file." + return 1 # Return with an error status + fi +} + + +# wait till db service is ready +until psql ${DATABASE_URL%/*} -c '\q'; do + >&2 echo "Postgres is unavailable - sleeping" + sleep 5 +done + +until curl --fail ${MASTER_HEALTH_URL}; do + >&2 echo "Master zksync not ready yet, sleeping" + sleep 5 +done + + +# Normally, the /etc/env and /var/lib/zksync/data should be mapped to volumes +# so that they are persisted between docker restarts - which would allow even faster starts. + +# We use the existance of this init file to decide whether to restart or not. +INIT_FILE="/var/lib/zksync/data/INIT_COMPLETED.remove_to_reset" + +if [ -f "$INIT_FILE" ]; then + echo "Initialization was done in the past - simply starting server" +else + echo "Initialing local environment" + + mkdir -p /var/lib/zksync/data + + update_config "/etc/env/base/private.toml" "database_url" "$DATABASE_URL" + update_config "/etc/env/base/private.toml" "database_prover_url" "$DATABASE_PROVER_URL" + update_config "/etc/env/base/eth_client.toml" "web3_url" "$ETH_CLIENT_WEB3_URL" + # Put database in a special /var/lib directory so that it is persisted between docker runs. + update_config "/etc/env/base/database.toml" "path" "/var/lib/zksync/data" + update_config "/etc/env/base/database.toml" "state_keeper_db_path" "/var/lib/zksync/data/state_keeper" + update_config "/etc/env/base/database.toml" "backup_path" "/var/lib/zksync/data/backups" + + # Updates all the stuff (from the '/etc/master_env') + zk f yarn --cwd /infrastructure/local-setup-preparation join + + + zk config compile + + zk db reset + + # Perform initialization + + ## not needed - reuse one from the 'base' chain + #zk contract deploy-verifier + #zk run deploy-erc20 dev # (created etc/tokens/localhost) + + ## init bridgehub state transition + # not needed - reuse them from basic chain + # zk contract deploy # (deploy L1) + # not needed + # zk contract initialize-governance + # zk contract initialize-validator + + ## init hyperchain + ## -- this is done in a different way now + zk contract register-hyperchain + ## - this just worked. + zk f zksync_server --genesis + + + zk contract deploy-l2-through-l1 + + # Don't setup rich accounts (as this might mess up the 'main' operator nonces). + # zk f yarn --cwd /infrastructure/local-setup-preparation start + + # Create init file. + echo "System initialized. Please remove this file if you want to reset the system" > $INIT_FILE + +fi + +# start server +zk f zksync_server diff --git a/infrastructure/local-setup-preparation/package.json b/infrastructure/local-setup-preparation/package.json index c319532d19dd..1dc00029b12a 100644 --- a/infrastructure/local-setup-preparation/package.json +++ b/infrastructure/local-setup-preparation/package.json @@ -13,6 +13,7 @@ "@types/node": "^18.19.15" }, "scripts": { - "start": "ts-node ./src/index.ts" + "start": "ts-node ./src/index.ts", + "join": "ts-node ./src/join_hyperchain.ts" } } \ No newline at end of file diff --git a/infrastructure/local-setup-preparation/src/join_hyperchain.ts b/infrastructure/local-setup-preparation/src/join_hyperchain.ts new file mode 100644 index 000000000000..1600dba5abb0 --- /dev/null +++ b/infrastructure/local-setup-preparation/src/join_hyperchain.ts @@ -0,0 +1,86 @@ +import fs from 'fs'; +import path from 'path'; +import { ethers } from 'ethers'; +import { getEthersProvider, getWalletKeys } from './utils'; +import assert from 'assert'; + +async function joinHyperchain() { + const chainId = process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!; + assert(chainId != '270', `Your chain id is set to 270 - are you sure`); + + const ethProvider = getEthersProvider(); + const operatorWallet = ethers.Wallet.createRandom(); + console.log(`Operator: ${operatorWallet.address}`); + const blobOperatorWallet = ethers.Wallet.createRandom(); + console.log(`Blob Operator: ${blobOperatorWallet.address}`); + + const allWalletKeys = getWalletKeys(); + + const richWalletKey = allWalletKeys[allWalletKeys.length - 1]; + + const richAccount = new ethers.Wallet(richWalletKey.privateKey, ethProvider); + + for (const addr of [operatorWallet.address, blobOperatorWallet.address]) { + const tx = { + to: addr, + // Convert Ether to Wei + value: ethers.utils.parseEther('100') + }; + await richAccount.sendTransaction(tx); + } + console.log(`Eth sent to operator accounts`); + + const inputFilePath = process.env.MASTER_ENV_FILE!; + const outputFilePath = path.resolve('/etc/env/l1-inits', '.init.env'); + const varsToKeep = [ + 'CONTRACTS_BRIDGEHUB_PROXY_ADDR', + 'CONTRACTS_STATE_TRANSITION_PROXY_ADDR', + 'CONTRACTS_ADMIN_FACET_ADDR', + 'CONTRACTS_MAILBOX_FACET_ADDR', + 'CONTRACTS_EXECUTOR_FACET_ADDR', + 'CONTRACTS_GETTERS_FACET_ADDR', + 'CONTRACTS_DIAMOND_INIT_ADDR', + 'CONTRACTS_BLOB_VERSIONED_HASH_RETRIEVER_ADDR', + 'CONTRACTS_VERIFIER_ADDR', + 'CONTRACTS_L1_MULTICALL3_ADDR', + 'CONTRACTS_VALIDATOR_TIMELOCK_ADDR', + 'CONTRACTS_GOVERNANCE_ADDR' + ]; + + try { + const data = fs.readFileSync(inputFilePath, 'utf8'); + + const lines = data.split(/\r?\n/); + // Filter and map lines to keep only specified variables + const filteredEnvVars = lines.filter((line) => { + const key = line.split('=')[0]; + return varsToKeep.includes(key); + }); + + filteredEnvVars.push(`ETH_SENDER_SENDER_OPERATOR_PRIVATE_KEY=${operatorWallet.privateKey}`); + filteredEnvVars.push(`ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR=${operatorWallet.address}`); + filteredEnvVars.push(`ETH_SENDER_SENDER_OPERATOR_BLOBS_PRIVATE_KEY=${blobOperatorWallet.privateKey}`); + filteredEnvVars.push(`ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR=${blobOperatorWallet.address}`); + + // Prepare the content to write to the output file + const outputContent = filteredEnvVars.join('\n'); + + // Write the filtered environment variables to the output file + fs.writeFileSync(outputFilePath, outputContent, 'utf8'); + console.log('Filtered environment variables have been written to the output file.'); + } catch (error) { + console.error('Failed to process environment variables:', error); + } +} + +async function main() { + await joinHyperchain(); +} + +main() + .then(() => { + console.log('Successfully joined hyperchain!'); + }) + .catch((e) => { + console.log(`Execution failed with error ${e}`); + }); From 98d5336e011ee29793f9ba1f37831a1c58f1fa9c Mon Sep 17 00:00:00 2001 From: mm Date: Tue, 7 May 2024 12:04:59 +0200 Subject: [PATCH 2/4] Moved back to single entrypoint --- .dockerignore | 1 - docker/local-node/Dockerfile | 1 - docker/local-node/entrypoint.sh | 41 +++++++--- docker/local-node/entrypoint_slave.sh | 113 -------------------------- 4 files changed, 31 insertions(+), 125 deletions(-) delete mode 100755 docker/local-node/entrypoint_slave.sh diff --git a/.dockerignore b/.dockerignore index 98dc6e35e0b3..603386e55e3b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,7 +1,6 @@ * !docker/prover/prover-entry.sh !docker/local-node/entrypoint.sh -!docker/local-node/entrypoint_slave.sh !docker/external-node/entrypoint.sh !docker/contract-verifier/install-all-solc.sh !etc/test_config diff --git a/docker/local-node/Dockerfile b/docker/local-node/Dockerfile index 46a0c6106349..c0592f89d563 100644 --- a/docker/local-node/Dockerfile +++ b/docker/local-node/Dockerfile @@ -70,6 +70,5 @@ RUN mkdir /etc/env/l1-inits && mkdir /etc/env/l2-inits # setup entrypoint script COPY ./docker/local-node/entrypoint.sh /usr/bin/ -COPY ./docker/local-node/entrypoint_slave.sh /usr/bin/ ENTRYPOINT ["entrypoint.sh"] diff --git a/docker/local-node/entrypoint.sh b/docker/local-node/entrypoint.sh index 00784e6855f4..381bde189bb5 100755 --- a/docker/local-node/entrypoint.sh +++ b/docker/local-node/entrypoint.sh @@ -44,6 +44,16 @@ until psql ${DATABASE_URL%/*} -c '\q'; do sleep 5 done +if [ -z "$MASTER_URL" ]; then + echo "Running as zksync master" +else + # If running in slave mode - wait for the master to be up and running. + echo "Waiting for zksync master to init hyperchain" + until curl --fail ${MASTER_HEALTH_URL}; do + >&2 echo "Master zksync not ready yet, sleeping" + sleep 5 + done +fi # Normally, the /etc/env and /var/lib/zksync/data should be mapped to volumes # so that they are persisted between docker restarts - which would allow even faster starts. @@ -66,19 +76,28 @@ else update_config "/etc/env/base/database.toml" "state_keeper_db_path" "/var/lib/zksync/data/state_keeper" update_config "/etc/env/base/database.toml" "backup_path" "/var/lib/zksync/data/backups" + + if [ -z "$MASTER_URL" ]; then + echo "Starting with hyperchain" + else + # Updates all the stuff (from the '/etc/master_env') - it assumes that it is mapped via docker compose. + zk f yarn --cwd /infrastructure/local-setup-preparation join + fi + zk config compile zk db reset - # Perform initialization - - zk contract deploy-verifier - zk run deploy-erc20 dev # (created etc/tokens/localhost) - - ## init bridgehub state transition - zk contract deploy # (deploy L1) - zk contract initialize-governance - zk contract initialize-validator + # Perform initialization (things needed to be done only if you're running in the master mode) + if [ -z "$MASTER_URL" ]; then + zk contract deploy-verifier + zk run deploy-erc20 dev # (created etc/tokens/localhost) + + ## init bridgehub state transition + zk contract deploy # (deploy L1) + zk contract initialize-governance + zk contract initialize-validator + fi ## init hyperchain zk contract register-hyperchain @@ -87,7 +106,9 @@ else zk contract deploy-l2-through-l1 - zk f yarn --cwd /infrastructure/local-setup-preparation start + if [ -z "$MASTER_URL" ]; then + zk f yarn --cwd /infrastructure/local-setup-preparation start + fi # Create init file. echo "System initialized. Please remove this file if you want to reset the system" > $INIT_FILE diff --git a/docker/local-node/entrypoint_slave.sh b/docker/local-node/entrypoint_slave.sh deleted file mode 100755 index 338d42fc5150..000000000000 --- a/docker/local-node/entrypoint_slave.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/bash -set -ea - -# These 3 env variables must be provided. -if [ -z "$DATABASE_URL" ]; then - echo "ERROR: DATABASE_URL is not set." - exit 1 -fi - -if [ -z "$DATABASE_PROVER_URL" ]; then - echo "ERROR: DATABASE_PROVER_URL is not set." - exit 1 -fi - -if [ -z "$ETH_CLIENT_WEB3_URL" ]; then - echo "ERROR: ETH_CLIENT_WEB3_URL is not set." - exit 1 -fi - -# Updates the value in the .toml config. -update_config() { - # Assigning arguments to readable variable names - local file="$1" - local parameter="$2" - local new_value="$3" - local pattern="^${parameter} =.*$" - - # Check if the parameter exists in the file - if grep -q "$pattern" "$file"; then - # The parameter exists, so replace its value - sed -i "s!$pattern!${parameter} =\"${new_value}\"!" "$file" - echo "Update successful for $parameter in $file." - else - # The parameter does not exist in the file, output error message and return non-zero status - echo "Error: '$parameter' not found in $file." - return 1 # Return with an error status - fi -} - - -# wait till db service is ready -until psql ${DATABASE_URL%/*} -c '\q'; do - >&2 echo "Postgres is unavailable - sleeping" - sleep 5 -done - -until curl --fail ${MASTER_HEALTH_URL}; do - >&2 echo "Master zksync not ready yet, sleeping" - sleep 5 -done - - -# Normally, the /etc/env and /var/lib/zksync/data should be mapped to volumes -# so that they are persisted between docker restarts - which would allow even faster starts. - -# We use the existance of this init file to decide whether to restart or not. -INIT_FILE="/var/lib/zksync/data/INIT_COMPLETED.remove_to_reset" - -if [ -f "$INIT_FILE" ]; then - echo "Initialization was done in the past - simply starting server" -else - echo "Initialing local environment" - - mkdir -p /var/lib/zksync/data - - update_config "/etc/env/base/private.toml" "database_url" "$DATABASE_URL" - update_config "/etc/env/base/private.toml" "database_prover_url" "$DATABASE_PROVER_URL" - update_config "/etc/env/base/eth_client.toml" "web3_url" "$ETH_CLIENT_WEB3_URL" - # Put database in a special /var/lib directory so that it is persisted between docker runs. - update_config "/etc/env/base/database.toml" "path" "/var/lib/zksync/data" - update_config "/etc/env/base/database.toml" "state_keeper_db_path" "/var/lib/zksync/data/state_keeper" - update_config "/etc/env/base/database.toml" "backup_path" "/var/lib/zksync/data/backups" - - # Updates all the stuff (from the '/etc/master_env') - zk f yarn --cwd /infrastructure/local-setup-preparation join - - - zk config compile - - zk db reset - - # Perform initialization - - ## not needed - reuse one from the 'base' chain - #zk contract deploy-verifier - #zk run deploy-erc20 dev # (created etc/tokens/localhost) - - ## init bridgehub state transition - # not needed - reuse them from basic chain - # zk contract deploy # (deploy L1) - # not needed - # zk contract initialize-governance - # zk contract initialize-validator - - ## init hyperchain - ## -- this is done in a different way now - zk contract register-hyperchain - ## - this just worked. - zk f zksync_server --genesis - - - zk contract deploy-l2-through-l1 - - # Don't setup rich accounts (as this might mess up the 'main' operator nonces). - # zk f yarn --cwd /infrastructure/local-setup-preparation start - - # Create init file. - echo "System initialized. Please remove this file if you want to reset the system" > $INIT_FILE - -fi - -# start server -zk f zksync_server From ffbe86a83f1bb9d9201d9816aea414aa616683ea Mon Sep 17 00:00:00 2001 From: mm Date: Tue, 7 May 2024 18:39:26 +0200 Subject: [PATCH 3/4] Added padding for gas --- .../local-setup-preparation/src/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/infrastructure/local-setup-preparation/src/index.ts b/infrastructure/local-setup-preparation/src/index.ts index c2179bd407a0..805d13aadcdb 100644 --- a/infrastructure/local-setup-preparation/src/index.ts +++ b/infrastructure/local-setup-preparation/src/index.ts @@ -25,12 +25,14 @@ async function depositWithRichAccounts() { const gasPrice = await ethProvider.getGasPrice(); const contract = new ethers.Contract(process.env.CONTRACTS_BRIDGEHUB_PROXY_ADDR, utils.BRIDGEHUB_ABI, ethProvider); - const expectedCost = await contract.l2TransactionBaseCost( - chainId, - gasPrice, - DEPOSIT_L2_GAS_LIMIT, - utils.DEFAULT_GAS_PER_PUBDATA_LIMIT - ); + const expectedCost = + (await contract.l2TransactionBaseCost( + chainId, + gasPrice, + DEPOSIT_L2_GAS_LIMIT, + utils.DEFAULT_GAS_PER_PUBDATA_LIMIT + )) * 1.5; + // We multiply the expected cost with 1.5 (in case gas price changes a little between calls - especially when we send 10 in a row). for (const wallet of wallets) { if (!(await isOperator(chainId, wallet.address))) { From a274d5c48115e2263ae9ecdf8360e485b3b1f93b Mon Sep 17 00:00:00 2001 From: mm Date: Wed, 8 May 2024 14:50:30 +0200 Subject: [PATCH 4/4] added 'vec' to dictionary --- checks-config/era.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/checks-config/era.dic b/checks-config/era.dic index 55b78766d257..28b326ce2812 100644 --- a/checks-config/era.dic +++ b/checks-config/era.dic @@ -673,6 +673,7 @@ crypto callee Subcalls Vec +vec vecs L1Messenger SystemL2ToL1Log