diff --git a/.dockerignore b/.dockerignore index 528c0ed9793a..523279722d29 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,7 @@ * !docker/prover/prover-entry.sh !docker/local-node/entrypoint.sh +!docker/local-node/zkstack !docker/external-node/entrypoint.sh !docker/contract-verifier/install-all-solc.sh !etc/test_config @@ -25,7 +26,6 @@ keys/setup !contracts/ !setup_2\^26.key !setup_2\^24.key -!setup_compact.key # It's required to remove .git from contracts, # otherwise yarn tries to use .git parent directory that # doesn't exist. @@ -42,9 +42,15 @@ contracts/.git !bellman-cuda !prover/data/ !.github/release-please/manifest.json +!zkstack_cli +!chains +!usr/local/bin +!usr/local/bin/zkstack !etc/env/file_based !etc/env/dev.toml !etc/env/consensus_secrets.yaml !etc/env/consensus_config.yaml !rust-toolchain +!ZkStack.yaml +!docker-compose.yml \ No newline at end of file diff --git a/docker/local-node/Dockerfile b/docker/local-node/Dockerfile index fce2cd9a8218..6a87500e0706 100644 --- a/docker/local-node/Dockerfile +++ b/docker/local-node/Dockerfile @@ -28,8 +28,7 @@ RUN cargo install sqlx-cli --version 0.8.0 # Copy required packages while preserving the folders structure from the repo # It's required because these packages use relative paths to the SDK -# Copy `zk` tool -COPY infrastructure/zk /infrastructure/zk + # Copy `local-setup-preparation` tool COPY infrastructure/local-setup-preparation /infrastructure/local-setup-preparation # Copy dev configs @@ -38,29 +37,34 @@ COPY etc/env /etc/env COPY etc/test_config /etc/test_config # Copy all the L1 contracts so they can be deployed COPY contracts /contracts/ - +COPY core/ /core # Set `ZKSYNC_HOME` to the root (required for `zk` tool) ENV ZKSYNC_HOME=/ # Set `LOCAL_SETUP` variable to modify `zk` tool behavior ENV ZKSYNC_LOCAL_SETUP=true # Disable all checks ENV ZKSYNC_ACTION=dont_ask - +# Env in Docker +ENV IN_DOCKER=1 # Build all the required TS packages -# Build `zk` tool -RUN cd /infrastructure/zk && yarn && yarn build && cd / # Build `local-setup-preparation` tool -RUN cd /infrastructure/local-setup-preparation && yarn && cd / +# RUN cd /infrastructure/local-setup-preparation && yarn && cd / # Build L1 contracts package (contracts themselves should be already built) RUN cd /contracts/l1-contracts && yarn && cd / # Same for L2 contracts RUN cd /contracts/l2-contracts && yarn && cd / +# Same for L1-da contracts +RUN cd /contracts/da-contracts && yarn && cd / -# Copy the ZK tool binary -COPY bin/zk /bin/zk +# Copy the ZK stack tool Library +COPY zkstack_cli /zkstack_cli +# Copy the configs for chain +COPY chains/era /chains/era # Copy package json (which gives us yarn workspace - and makes commands more similar to what we normally run) COPY package.json / +# Copy rust toolchain (so the compilation can be done with correct nightly) +COPY rust-toolchain / # Copy DAL - needed to setup database schemas. COPY core/lib/dal core/lib/dal @@ -71,4 +75,58 @@ RUN mkdir /etc/env/l1-inits && mkdir /etc/env/l2-inits # setup entrypoint script COPY ./docker/local-node/entrypoint.sh /usr/bin/ +COPY ./docker-compose.yml /docker-compose.yml +COPY ./ZkStack.yaml /ZkStack.yaml + +# Install Docker +RUN apt-get update && apt-get install -y docker.io + +# Configure Docker repository +# RUN apt-get update && \ +# apt-get install -y ca-certificates curl gnupg && \ +# mkdir -m 0755 /etc/apt/keyrings && \ +# curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ +# echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && \ +# apt-get update && \ +# apt-get install -y docker-compose-plugin && \ +# \ +# # Install Foundry for zkSync +# curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash + +# Persist environment variables +# ENV PATH=$HOME/.foundry/bin:$PATH +# ENV LIBCLANG_PATH=/usr/lib/llvm-14/lib +ENV COMPOSE_PROJECT_NAME=my_project_name +ENV GITHUB_WORKSPACE=my_github_workspace + +# Install additional dependencies +RUN apt-get update && apt-get install -y \ + clang llvm-dev libclang-dev \ + ca-certificates curl gnupg \ + && curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash + +# Install required dependencies including Docker +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates curl gnupg lsb-release \ + && mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \ + && apt-get update \ + && apt-get install -y docker-compose-plugin \ + && rm -rf /var/lib/apt/lists/* + +# Set persistent environment variables +ENV LIBCLANG_PATH=/usr/lib/llvm-14/lib +ENV PATH="/usr/local/cargo/bin:/root/.foundry/bin:$PATH" + +RUN ./zkstack_cli/zkstackup/install -g --path ./zkstack_cli/zkstackup/zkstackup \ + && zkstackup -g --local --cargo-features gateway + + +# CMD ["/bin/bash"] + ENTRYPOINT ["entrypoint.sh"] + + + +# Root hash mismatched: From config: 0xd8c9be7efb705e7dcf529c14fce7048ea99dea9eab6a6b4e5f8de1ebf4f2ebf2, Calculated 0xb6779307f23867c798513845edb67ce0eca31a433e3c86f46a6961d0567a067d \ No newline at end of file diff --git a/docker/local-node/entrypoint.sh b/docker/local-node/entrypoint.sh index e57d849802ec..9987fcbb368d 100755 --- a/docker/local-node/entrypoint.sh +++ b/docker/local-node/entrypoint.sh @@ -17,178 +17,109 @@ if [ -z "$ETH_CLIENT_WEB3_URL" ]; then exit 1 fi -# Updates the value in the .toml config or .env file. +# Function to update a key in a YAML file update_config() { - # Assigning arguments to readable variable names local file="$1" - local parameter="$2" + local key="$2" local new_value="$3" - local pattern_toml="^${parameter} =.*$" - local pattern_env="^${parameter}=.*$" - - # Check if the parameter exists in the file - if grep -q "$pattern_toml" "$file"; then - # The parameter exists in the .toml file, so replace its value - sed -i "s!$pattern_toml!${parameter} = \"$new_value\"!" "$file" - echo "Update successful for $parameter in $file." - elif grep -q "$pattern_env" "$file"; then - # The parameter exists in the .env file, so replace its value - sed -i "s!$pattern_env!${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 -} -# Reads the value of the parameter from the .toml config or .env file. -read_value_from_config() { - local file="$1" - local parameter="$2" - local pattern_toml="^${parameter} =.*$" - local pattern_env="^${parameter}=.*$" - local res="" - - # Check if the parameter exists in the file - if grep -q "$pattern_toml" "$file"; then - # The parameter exists in the .toml file, so extract its value - res=$(grep "$pattern_toml" "$file" | sed "s/${parameter} = //; s/\"//g") - elif grep -q "$pattern_env" "$file"; then - # The parameter exists in the .env file, so extract its value - res=$(grep "$pattern_env" "$file" | sed "s/${parameter}=//; s/\"//g") - 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 + # Escape special characters for sed + local escaped_key=$(echo "$key" | sed 's/\./\\./g') + local pattern="^\\s*${escaped_key}:.*$" - if [ -z "$res" ]; then - echo "ERROR: $parameter is not set in $file." - exit 1 + # Check if the key exists in the file + if grep -qE "$pattern" "$file"; then + # Update the existing key + sed -i "s|$pattern|${key}: $new_value|" "$file" + echo "Updated '$key' in $file." + else + # Append the key if it doesn't exist + echo "$key: $new_value" >> "$file" + echo "Added '$key' to $file." fi - - echo $res } + # wait till db service is ready until psql ${DATABASE_URL%/*} -c '\q'; do echo >&2 "Postgres is unavailable - sleeping" sleep 5 done +echo "Initialing local environment" + +# Determine the correct config path based on MASTER_URL if [ -z "$MASTER_URL" ]; then - echo "Running as zksync master" + CONFIG_PATH="/chains/era/configs" + echo "Updating configuration for MASTER chain..." 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 - echo >&2 "Master zksync not ready yet, sleeping" - sleep 5 - done -fi - -if [ -n "$LEGACY_BRIDGE_TESTING" ]; then - if [ -z "$MASTER_URL" ]; then - echo "Running in legacy bridge testing mode" - else - # LEGACY_BRIDGE_TESTING flag is for the master only - unset LEGACY_BRIDGE_TESTING - fi + CONFIG_PATH="/chains/custom_token/configs" + echo "Updating configuration for Custom Token chain..." fi +# update_config "/chains/era/configs/secrets.yaml" "server_url" "$DATABASE_URL" +# update_config "/chains/era/configs/secrets.yaml" "prover_url" "$DATABASE_PROVER_URL" +# update_config "/chains/era/configs/secrets.yaml" "l1_rpc_url" "$ETH_CLIENT_WEB3_URL" -# 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" - - if [ -n "$LEGACY_BRIDGE_TESTING" ]; then - # making era chain id same as current chain id for legacy bridge testing - chain_eth_zksync_network_id=$(read_value_from_config "/etc/env/base/chain.toml" "zksync_network_id") - update_config "/etc/env/base/contracts.toml" "ERA_CHAIN_ID" "$chain_eth_zksync_network_id" - fi - - 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 (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 - - - if [ -z "$CUSTOM_BASE_TOKEN" ]; then - echo "Starting chain with ETH as gas token" - - if [ -z "$VALIDIUM_MODE" ]; then - ## init hyperchain in rollup mode - zk contract register-hyperchain - else - zk contract register-hyperchain --deployment-mode 1 - fi - else - echo "Starting chain with custom gas token $CUSTOM_BASE_TOKEN" - zk contract register-hyperchain --base-token-name $CUSTOM_BASE_TOKEN - fi - - - zk f zksync_server --genesis - - deploy_l2_args="" - if [ -n "$LEGACY_BRIDGE_TESTING" ]; then - # setting the flag for legacy bridge testing - deploy_l2_args="--local-legacy-bridge-testing" - fi +# Extract the database name (everything after the last '/') +SERVER_DB_NAME="${DATABASE_URL##*/}" - zk contract deploy-l2-through-l1 $deploy_l2_args - - if [ -z "$MASTER_URL" ]; then - zk f yarn --cwd /infrastructure/local-setup-preparation start - fi +# Extract the database URL without the database name +SERVER_DB_URL="${DATABASE_URL%/*}" - if [ -n "$LEGACY_BRIDGE_TESTING" ]; then - # making era address same as current address for legacy bridge testing - contracts_diamond_proxy_addr=$(read_value_from_config "/etc/env/target/dev.env" "CONTRACTS_DIAMOND_PROXY_ADDR") - update_config "/etc/env/target/dev.env" "CONTRACTS_ERA_DIAMOND_PROXY_ADDR" "$contracts_diamond_proxy_addr" +if [ -z "$MASTER_URL" ]; then + echo "Running as zksync master" - # setup-legacy-bridge-era waits for the server to be ready, so starting it in the background - zk contract setup-legacy-bridge-era & - fi + update_config "$CONFIG_PATH/secrets.yaml" "server_url" "$DATABASE_URL" + update_config "$CONFIG_PATH/secrets.yaml" "prover_url" "$DATABASE_PROVER_URL" + update_config "$CONFIG_PATH/secrets.yaml" "l1_rpc_url" "$ETH_CLIENT_WEB3_URL" - # Create init file. - echo "System initialized. Please remove this file if you want to reset the system" >$INIT_FILE + echo "Configuration updated successfully." -fi + zkstack ecosystem init --deploy-paymaster --deploy-erc20 \ + --deploy-ecosystem --l1-rpc-url=$ETH_CLIENT_WEB3_URL \ + --server-db-url="$SERVER_DB_URL" \ + --server-db-name="$SERVER_DB_NAME" \ + --ignore-prerequisites --verbose \ + --observability=false \ + --update-submodules=false -# start server -zk f zksync_server + # start server + zkstack server +else + zkstack chain create \ + --chain-name custom_token \ + --chain-id 275 \ + --prover-mode no-proofs \ + --wallet-creation localhost \ + --l1-batch-commit-data-generator-mode rollup \ + --base-token-address ${CUSTOM_TOKEN_ADDRESS} \ + --base-token-price-nominator 314 \ + --base-token-price-denominator 1000 \ + --set-as-default false \ + --ignore-prerequisites \ + --evm-emulator false \ + --update-submodules=false + + update_config "$CONFIG_PATH/secrets.yaml" "server_url" "$DATABASE_URL" + update_config "$CONFIG_PATH/secrets.yaml" "prover_url" "$DATABASE_PROVER_URL" + update_config "$CONFIG_PATH/secrets.yaml" "l1_rpc_url" "$ETH_CLIENT_WEB3_URL" + + echo "Configuration updated successfully." + + zkstack chain init \ + --deploy-paymaster \ + --l1-rpc-url=$ETH_CLIENT_WEB3_URL \ + --server-db-url="$SERVER_DB_URL" \ + --server-db-name="$SERVER_DB_NAME" \ + --chain custom_token \ + --validium-type no-da \ + --update-submodules=false + # # 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 + # echo >&2 "Master zksync not ready yet, sleeping" + # sleep 5 + # done + # start server + zkstack server --chain custom_token +fi \ No newline at end of file diff --git a/zkstack_cli/crates/common/src/ethereum.rs b/zkstack_cli/crates/common/src/ethereum.rs index 96ec8b4f3597..eebaefccb578 100644 --- a/zkstack_cli/crates/common/src/ethereum.rs +++ b/zkstack_cli/crates/common/src/ethereum.rs @@ -8,6 +8,7 @@ use ethers::{ providers::Middleware, types::{Address, TransactionRequest}, }; +use tokio::time::sleep; use zkstack_cli_types::TokenInfo; use crate::{logger, wallets::Wallet}; @@ -102,6 +103,8 @@ pub async fn mint_token( let mut pending_txs = vec![]; for call in &pending_calls { + sleep(Duration::from_secs(2)).await; // ✅ Wait for 2 seconds + let call = call.send().await; match call { // It's safe to set such low number of confirmations and low interval for localhost