Setup production ZKNode#
X Layer is now available on the Mainnet and Testnet for developers to launch smart contracts, execute transactions, and experiment with the network. This tutorial extends the exploration by allowing developers to launch their own node on the Public network. Before we begin, this document is fairly technical and requires prior exposure to Docker and CLI. Post spinning up your ZKNode instance, you will be able to run the Synchronizer and utilize the JSON-RPC interface.
Prerequisites#
This tutorial assumes that you have docker-compose already installed. If you need any help with the installation, please check the official docker-compose installation guide.
Minimum System requirements#
- 16GB RAM
- 4-core CPU
- 1 TB Storage (This will increase over time)
Network components#
Here is a list of crucial network components that are required before you can run the ZKNode:
- Ethereum Node - Use geth or any service providing a JSON RPC interface for accessing the layer 1 network
- X Layer-Node (or ZKNode) - layer 2 network
- Synchronizer - Responsible for synchronizing data between layer 1 and layer 2
- JSON RPC Server - Interface to layer 2 network
- State DB - Save the layer 2 account, block and tx data.
Let’s set up each of the above components!
Ethereum node setup#
The Ethereum RPC Node is the first component to be deployed because ZKNode needs to synchronize blocks and transactions on layer 1. You can invoke the ETH RPC (Mainnet: Ethereum OR Testnet: Sepolia) service through any of the following methods:
- Third-party RPC services, such as Infura or Ankr.
- Set up your own Ethereum node. Follow the instructions provided in this guide to set up and install Geth.
- Set up an Erigon RPC Node here:
Installing#
Once the layer 1 RPC component is complete, we can start the ZKNode setup. This is the most straightforward way to run a ZKNode and it’s fine for most use cases. Furthermore, this method is purely subjective and feel free to run this software in a different manner. For example, Docker is not required, you could simply use the Go binaries directly. Let’s start setting up our ZKNode:
- Download the installation script
mkdir -p ./xlayer-node && cd ./xlayer-node
# mainnet
curl -fsSL https://raw.githubusercontent.com/okx/Deploy/main/setup/zknode/run_xlayer_mainnet.sh | bash -s init && cp ./mainnet/example.env ./mainnet/.env
# testnet
curl -fsSL https://raw.githubusercontent.com/okx/Deploy/main/setup/zknode/run_xlayer_testnet.sh | bash -s init && cp ./testnet/example.env ./testnet/.env
- The example.env file must be modified according to your configurations. Edit the .env file with your favourite editor (we’ll use vim in this guide):
# mainnet
vim ./mainnet/.env
# testnet
vim ./testnet/.env
# URL of a JSON RPC for Ethereum mainnet or Sepolia testnet
XLAYER_NODE_ETHERMAN_URL = "http://your.L1node.url"
# PATH WHERE THE STATEDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA
XLAYER_NODE_STATEDB_DATA_DIR = "./xlayer_mainnet_data/statedb" # OR ./xlayer_testnet_datastatedb/ for testnet
# PATH WHERE THE POOLDB POSTGRES CONTAINER WILL STORE PERSISTENT DATA #
XLAYER_NODE_POOLDB_DATA_DIR = "./xlayer_mainnet_data/pooldb" # OR ./xlayer_testnet_data/pooldb/ for testnet
- Restore the latest layer 2 snapshot locally database for synchronizing layer 2 data quickly.
# mainnet
./run_xlayer_mainnet.sh restore
# testnet
./run_xlayer_testnet.sh restore
Starting#
Use the below command to start the ZKNode instance:
# mainnet
./run_xlayer_mainnet.sh start
# testnet
./run_xlayer_testnet.sh start
docker ps -a
You will see a list of the following containers :
- xlayer-rpc
- xlayer-sync
- xlayer-state-db
- xlayer-pool-db
- xlayer-prover
You should now be able to run queries to the JSON-RPC endpoint at http://localhost:8545. Run the following query to get the most recently synchronized layer 2 block; if you call it every few seconds, you should see the number grow:
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}' http://localhost:8545
Stopping#
Use the below command to stop the ZKNode instance:
# mainnet
./run_xlayer_mainnet.sh stop
# testnet
./run_xlayer_testnet.sh stop
Restarting#
Use the below command to stop the ZKNode instance:
# mainnet
./run_xlayer_mainnet.sh restart
# testnet
./run_xlayer_testnet.sh restart
Updating#
To update the ZKNode software, run the below command, and the file ./mainnet(or testnet)/.env
will be retained, the other config will be deleted.
# mainnet
./run_xlayer_mainnet.sh update
# testnet
./run_xlayer_testnet.sh update
Troubleshooting#
- It’s possible that the machine you’re using already uses some of the necessary ports. In this case, you can change them directly
./mainnet(testnet)/docker-compose.yml
. - If one or more containers are crashing, please check the logs using the command below:
docker ps -a
docker logs <cointainer_name>
Force resync From specific batch#
- Stop xlayer-sync and xlayer-rpc services
docker stop xlayer-sync
docker stop xlayer-rpc
- Select max verified batch
PGPASSWORD=state_password psql -h 127.0.0.1 -p 5432 -d state_db -U state_user
SELECT max(batch_num) FROM state.verified_batch;
# Use the batch_num above to perform the resync from a specific batch (e.g. 330000):
- Look for the target block and batch to delete
- Look for this batch in OK Link and get "Sequence Tx Hash" value (0xf5bcff8bc5e03be47e36d642d26f0551ff4a66094e1fb67c9e02ec739c7fca82)
- Go to previous batches (you can use "<" button) until you reach the first batch sequenced with the same "Sequence Tx Hash" (in this example 329992).
- Look for the "Sequence Tx Hash" in etherscan to get the layer 1 block where that tx was confirmed (in this example 5517146).
- Delete the block and batch
delete from state.block where block_num >= 5517146;
delete from state.batch where batch_num >= 329992;
- Start the sync service to sync again.