💻Bare Metal
Author: [ jLeopoldA ]
System Requirements
CPU
OS
RAM
DISK
The Zksync Archive Node has a size of <SIZE HERE> as of <DATE>
Pre-Requisites
Zksync requires PostgreSQL, Docker, Docker-Compose, an Ethereum L1, and a database dump.
Update and Clean System
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
Install Docker & Docker-Compose
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# Install Docker Packages including Docker Compose
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Verify Docker Engine Installation
sudo docker run hello-world
Firewall Configuration
Set Explicit Default Firewall Rules
sudo ufw default deny incoming && sudo ufw default allow outgoing
Allow SSH
sudo ufw allow 22/tcp
Allow RPC Connections with Zksync
sudo ufw allow 3060
Allow P2P & Metrics
sudo ufw allow 3322 && sudo ufw allow 3061
Enable Firewall
sudo ufw enable
Check Status & Current Rules of UFW
sudo ufw status verbose
PostgreSQL
Install PostgreSQL
sudo apt install postgresql postgresql-contrib
Set Password
# Enter the psql terminal
psql -U postgres
# Create password
ALTER ROLE postgres WITH PASSWORD 'password';
# Create Database for Zksync
CREATE DATABASE zksync_local_ext_node;
# Exit psql terminal
\q
Download and Import Database Dump
Download Database Dump
# Make Directory for Database
mkdir -p /root/zksync/dump
cd /root/zksync/dump
# This website provides database dumps
# https://en-backups.matterlabs.dev/
# Right click and copy the link you would like
nohup wget <selected_link> & disown
# Example Download Dump
nohup wget http://37.27.135.10:8080/ipfs/QmVWVRjw5DEuG5noaD7Ltcc4BGGCKEcjvL8CYFw5GcAzWD/external_node_latest.pgdump.sql.gz & disown
# Check Status of Download
tail -f nohup.out
Import Database Dump
# Remove previous nohup.out
rm nohup.out
# Import Database into zksync_local_ext_node
zcat external_node_backup_2024_12_13T05_05.sql.gz | nohup psql -U postgres -d zksync_local_ext_node
# Vague layout
zcat <your_downloaded_file> | nohup psql -U your_username_here -d your_database_name_here
# Check import status
tail -f nohup.out
# Check Database Size
psql -U postgres
SELECT pg_size_pretty(pg_database_size('zksync_local_ext_node'));
# Abstract Database Size Check
psql -U your_username_here
SELECT pg_size_pretty(pg_database_size('your_database_name_here'));
# Ensure database is done
ps aux | grep "nohup"
# If there are multiple responses like the below then it is still processing.
root 2602454 0.0 0.0 6544 2048 pts/0 S+ 22:33 0:00 grep --color=auto nohup
Ensure that your database has finished importing before proceeding to the next step.
Set up Zksync
Create Directories
# Extracted Content Directory
mkdir -p /root/zksync/repo/contracts
mkdir -p /root/zksync/repo/etc
mkdir -p /root/zksync/repo/usr/bin
mkdir -p /root/zksync/repo/migrations
# External Node Data Directory
mkdir -p /var/lib/zksync/db/ext-node/state_keeper
mkdir -p /var/lib/zksync/db/ext-node/lightweight
# Directory for Consensus Config
mkdir -p /etc/zksync/
Extract Zksync Binaries from Docker
# Pull latest Zksync Image
docker pull matterlabs/external-node:latest
# Copy necessary components to our created directories
docker cp $(docker run -it -d matterlabs/external-node:latest):/usr/bin/zksync_external_node /root/zksync/repo/usr/bin
docker cp $(docker run -it -d matterlabs/external-node:latest):/usr/bin/block_reverter /root/zksync/repo/usr/bin
docker cp $(docker run -it -d matterlabs/external-node:latest):/usr/bin/sqlx /root/zksync/repo/usr/bin
docker cp $(docker run -it -d matterlabs/external-node:latest):/contracts/. /root/zksync/repo/contracts
docker cp $(docker run -it -d matterlabs/external-node:latest):/etc/tokens/. /root/zksync/repo/etc/tokens/
docker cp $(docker run -it -d matterlabs/external-node:latest):/etc/ERC20/. /root/zksync/repo/etc/ERC20/
docker cp $(docker run -it -d matterlabs/external-node:latest):/etc/multivm_bootloaders/. /root/zksync/repo/etc/multivm_bootloaders/
docker cp $(docker run -it -d matterlabs/external-node:latest):/migrations/. /root/zksync/repo/migrations/
Perform Database Migration
cd /root/zksync/repo/usr/bin
# Set migration folder as source and specify database
nohup ./sqlx migrate info --source /root/FINAL/repo/migrations --database-url postgres://postgres:password@localhost/zksync_local_ext_node & disown
# When the above is done - remove uncessary file
rm nohup.out
# Run Database Migration
nohup ./sqlx migrate run --source /root/FINAL/repo/migrations --database-url postgres://postgres:password@localhost/zksync_local_ext_node & disown
Create Mainnet Consensus Configuration
# Create Mainnet Configuration
echo "server_addr: '0.0.0.0:3054'
public_addr: '127.0.0.1:3054'
debug_page_addr: '127.0.0.1:5000'
max_payload_size: 5000000
gossip_dynamic_inbound_limit: 100
gossip_static_outbound:
# preconfigured ENs owned by Matterlabs that you can connect to
- key: 'node:public:ed25519:68d29127ab03408bf5c838553b19c32bdb3aaaae9bf293e5e078c3a0d265822a'
addr: 'external-node-consensus-mainnet.zksync.dev:3054'
- key: 'node:public:ed25519:b521e1bb173d04bc83d46b859d1296378e94a40427a6beb9e7fdd17cbd934c11'
addr: 'external-node-moby-consensus-mainnet.zksync.dev:3054'" > /etc/zksync/mainnet_consensus_config.yaml
Create System Service
echo "[Unit]
Description=zkSync Era Node
After=network.target
[Service]
User=root
Environment=DATABASE_URL="postgres://postgres:password@localhost/zksync_local_ext_node"
Environment=DATABASE_POOL_SIZE=10
Environment=EN_HTTP_PORT=3060
Environment=EN_WS_PORT=3061
Environment=EN_HEALTHCHECK_PORT=3081
Environment=EN_PROMETHEUS_PORT=3322
Environment=EN_ETH_CLIENT_URL="https://ethereum-rpc.infradao.com"
Environment=EN_MAIN_NODE_URL="https://zksync2-mainnet.zksync.io"
Environment=EN_L1_CHAIN_ID=1
Environment=EN_L2_CHAIN_ID=324
Environment=EN_PRUNING_ENABLED=false
Environment=EN_STATE_CACHE_PATH="/var/lib/zksync/db/ext-node/state_keeper"
Environment=EN_MERKLE_TREE_PATH="/var/lib/zksync/db/ext-node/lightweight"
Environment=EN_SNAPSHOTS_RECOVERY_ENABLED="false"
Environment=EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL="zksync-era-mainnet-external-node-snapshots"
Environment=EN_SNAPSHOTS_OBJECT_STORE_MODE="GCSAnonymousReadOnly"
Environment=RUST_LOG="warn,zksync=info,zksync_core:metadata_calculator=debug,zksync_state=debug,zksync_utils=debug,zksync_web3_decl::client=error"
Environment=EN_CONSENSUS_CONFIG_PATH="/etc/zksync/mainnet_consensus_config.yaml"
Environment=EN_CONSENSUS_SECRETS="/var/lib/zksync/mainnet_consensus_secrets.yaml"
WorkingDirectory=/root/zksync/repo
ExecStart=/root/zksync/repo/usr/bin/zksync_external_node
Restart=on-failure
LimitNOFILE=1000000
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/zksync.service
Run Zksync Archive Node
Systemctl Commands for Zksync
systemctl daemon-reload # Reload systemctl
systemctl enable zksync.service # Enable Zksync
systemctl start zksync.service # Start Zksync
systemctl stop zksync.service # Stop Zksync
systemctl restart zksync.service # Restart Zksync
Query Zksync Node
# CHECK STATUS OF SYNC
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_syncing", "params":[], "id":1}' http://localhost:3060
##### The response should resemble the below
{"jsonrpc":"2.0","id":1,"result":{"startingBlock":"0x0","currentBlock":"0x3219750","highestBlock":"0x35fc3d7"}}
# CHECK LATEST BLOCK
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":1}' http://localhost:3060
##### The response should resemble the below
{"jsonrpc":"2.0","id":1,"result":"0x321afb7"}
Last updated