Lisk provides a cost-efficient, fast, and scalable Layer 2 (L2) network based on Optimism (OP) that is secured by Ethereum.
This repository contains information on how to run your own node on the Lisk network.
We recommend you the following hardware configuration to run a Lisk L2 node:
- a modern multi-core CPU with good single-core performance
- a minimum of 16 GB RAM (32 GB recommended)
- a locally attached NVMe SSD drive
- adequate storage capacity to accommodate both the snapshot restoration process (if restoring from snapshot) and chain data, ensuring a minimum of (2 * current_chain_size) + snapshot_size + 20%_buffer
- if running with docker, please install Docker Engine version 27.0.1 or higher
Note: If utilizing Amazon Elastic Block Store (EBS), ensure timing buffered disk reads are fast enough to avoid latency issues alongside the rate of new blocks added to Lisk during the initial synchronization process; io2 Block Express is recommended.
| Lisk Network | Status |
|---|---|
| Sepolia (Testnet) | ✅ |
| Mainnet | ✅ |
Note: Starting with Lisk Node v0.3.0, users running op-reth should set their
--chainflag to the network name instead of a genesis block filepath. We've removed the genesis block and will not be maintaining it in the repository going forward.
git clone https://github.com/LiskHQ/lisk-node.git
cd lisk-node-
Ensure you have an Ethereum L1 full node RPC available (not Lisk), and set the
OP_NODE_L1_ETH_RPCand theOP_NODE_L1_BEACONvariables (within the.env.*files, if using docker-compose). If running your own L1 node, it needs to be synced before the Lisk node will be able to fully sync. -
Please ensure that the environment file relevant to your network (
.env.sepolia, or.env.mainnet) is set for theenv_fileproperties at two places withindocker-compose.yml. By default, it is set to.env.mainnet. -
The
op-rethclient can be built in either themaxperf(default) orreleaseprofile. To learn more about them, please check reth's documentation on Optimizations. Set theRETH_BUILD_PROFILEenvironment variable accordingly.Note:
- Unless you are building
op-rethinreleaseprofile, please ensure that you have a machine with 32 GB RAM. - Additionally, if you have Docker Desktop installed on your system, please make sure to set
Memory limitto a minimum of16 GB.
It can be set underSettings -> Resources -> Resource Allocation -> Memory limit.
- Unless you are building
-
Run:
IMPORTANT: To run the node on Lisk Sepolia, first patch the Dockerfile with:git apply dockerfile-lisk-sepolia.patch
docker compose up --build --detach
-
You should now be able to
curlyour Lisk node:curl -s -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \ -H "Content-Type: application/json" http://localhost:8545
Please use the following client versions:
-
Before proceeding, please make sure to install the following dependency (this information is missing in the OP documentations linked below):
-
To build
op-nodefrom source, follow OP documentation on Building a Node from Source.- Before building the
op-node, please patch the code withop-node-lisk-sepolia.patchfor an unhandledSystemConfigevent emitted on Lisk Sepolia, resulting in errors on the Lisk nodes.git apply <path-to-op-node-lisk-sepolia.patch>
- Before building the
-
To build
op-rethfrom source, refer to theop-rethsource tree in theethereum-optimism/optimismrepository (pinned to the version above).
Set the following environment variable:
export DATADIR_PATH=... # Path to the folder where the op-reth data will be stored
op-reth and op-node communicate over the engine API authrpc. This communication can be secured with a shared secret which can be provided to both when starting the applications. In this case, the secret takes the form of a random 32-byte hex string and can be generated with:
openssl rand -hex 32 > jwt.txt
For more information refer to the OP documentation.
- Set
RETH_CHAINtoliskto run the node against Lisk Mainnet orlisk-sepoliato run it against Lisk Sepolia. - Navigate to your
rethdirectory and start service by running the command:
./target/maxperf/op-reth node \
-vvv \
--chain=$RETH_CHAIN \
--datadir="$DATADIR_PATH" \
--log.stdout.format log-fmt \
--authrpc.addr=0.0.0.0 \
--authrpc.port=8551 \
--authrpc.jwtsecret=PATH_TO_JWT_TEXT_FILE \
--ws \
--ws.origins="*" \
--ws.addr=0.0.0.0 \
--ws.port=8546 \
--ws.api=web3,debug,eth,net,txpool \
--http \
--http.corsdomain="*" \
--http.addr=0.0.0.0 \
--http.port=8545 \
--http.api=web3,debug,eth,net,txpool \
--metrics=0.0.0.0:6060 \
--disable-discovery \
--port=30303 \
--rollup.sequencer-http=SEQUENCER_HTTP \
--rollup.disable-tx-pool-gossipRefer to the reth configuration documentation for detailed information about available options.
Note:
--disable-discoveryand--bootnodesare mutually exclusive in practice — reth's bootnodes only take effect via the discovery protocol (discv4/discv5/DNS). If you want to seed peer discovery (e.g. for snap sync), drop--disable-discoveryand pass--bootnodes=<comma-separated enode URLs>instead. See Snap sync below.
Note:
Official Lisk Sequencer HTTP RPC endpoints:
- Lisk Sepolia: https://rpc.sepolia-api.lisk.com
- Lisk Mainnet: https://rpc.api.lisk.com
⚠️ Please consider using a private endpoint to connect to the sequencer when running your own node if you encounter rate limit issues. More information is available here: Private RPCs.
- Set
OP_NODE_NETWORKtolisk-mainnetto run the node against Lisk Mainnet orlisk-sepoliato run it against Lisk Sepolia. - Navigate to your
op-nodedirectory and start service by running the command:
./bin/op-node \
--network=$OP_NODE_NETWORK \
--l1=$OP_NODE_L1_ETH_RPC \
--l1.rpckind=$OP_NODE_L1_RPC_KIND \
--l1.beacon=$OP_NODE_L1_BEACON \
--l2=ws://localhost:8551 \
--l2.jwt-secret=PATH_TO_JWT_TEXT_FILEThe above command starts op-node in full sync mode. Depending on the chain length, the initial sync process could take significant time; varying from days to weeks.
INFO [06-26|13:31:20.389] Advancing bq origin origin=17171d..1bc69b:8300332 originBehind=false
For more information refer to the OP documentation.
Refer to the op-node configuration documentation for detailed information about available options.
Note:
Some L1 nodes (e.g. Erigon) do not support fetching storage proofs. You can work around this by specifying--l1.trustrpcwhen starting op-node (add it inop-node-entrypointand rebuild the docker image withdocker compose build.) Do not do this unless you fully trust the L1 node provider.
Note:
op-rethonly supports datadir snapshots: large download, fast restore, no data verification.- All snapshots are from archival nodes.
To enable auto-snapshot download and application, set the APPLY_SNAPSHOT environment variable to true when starting the node:
APPLY_SNAPSHOT=true docker compose up --build --detachYou can also download and apply a snapshot from a custom URL by setting the SNAPSHOT_URL environment variable. Supported formats are *.tar.gz, *.tar, and *.tar.lz4.
APPLY_SNAPSHOT=true SNAPSHOT_URL=<custom-snapshot-url> docker compose up --build --detachNote: Alternative snapshot sources hosted by Gelato:
- Lisk Mainnet: https://lisk.snapshots.gelato.cloud/index.html
- Lisk Sepolia: https://lisk.t.snapshots.gelato.cloud/index.html
Please follow the steps below:
-
Download the snapshot and the corresponding checksum. The latest snapshot name is listed at
latest-reth-datadir, available at:- Sepolia: https://snapshots.lisk.com/sepolia
- Mainnet: https://snapshots.lisk.com/mainnet
Alternative snapshot sources hosted by Gelato:
-
Verify the integrity of the downloaded snapshot with:
sha256sum -c <checksum-file-name>
-
Import the snapshot:
.taror.tar.gz:tar --directory $RETH_DATA_DIR -xf <path-to-datadir-snapshot>
.tar.lz4:# requires `lz4` to be installed tar --directory $RETH_DATA_DIR -I lz4 -xf <path-to-datadir-snapshot>
By default, the Lisk node runs in full sync mode. To enable snap sync (faster initial sync by fetching state from peers), uncomment the snap-sync block in your .env.* file:
OP_NODE_SYNCMODE=execution-layer— instructsop-nodeto defer block sync to the execution client.OP_RETH_BOOTNODES— comma-separated enode URLs used to bootstrap peer discovery. Snap sync needs P2P connectivity beyond the sequencer, so at least one working bootnode is required.
Note: For
op-reth, the docker entrypoint normally runs with--disable-discovery, which disables the discovery protocols (discv4/discv5/DNS) so the node won't automatically find peers. WhenOP_RETH_BOOTNODESis set, the entrypoint automatically drops--disable-discoverybecause reth's bootnodes only take effect via the discovery protocol — they are no-ops when discovery is turned off. If you build and runop-rethfrom source instead of via docker, remove--disable-discoveryfrom your command line when passing--bootnodes.
Sync speed depends on your L1 node, as the majority of the chain is derived from data submitted to the L1. You can check your syncing status using the optimism_syncStatus RPC on the op-node container. Example:
command -v jq &> /dev/null || { echo "jq is not installed" 1>&2 ; }
echo Latest synced block behind by: \
$((($( date +%s )-\
$( curl -s -d '{"id":0,"jsonrpc":"2.0","method":"optimism_syncStatus"}' -H "Content-Type: application/json" http://localhost:9545 |
jq -r .result.unsafe_l2.timestamp))/60)) minutes
For developers and node operators who need to interact with the node programmatically, here are the relevant API documentation links:
-
op-node: Comprehensive JSON-RPC API documentation for the Optimism node -
op-reth: Detailed JSON-RPC documentation for the Reth client