Running a Scroll L2geth Node
This guide will walk you through setting up your own Scroll node using Docker with snapshot.
Key Differences from Scroll Sepolia
- Required binary version:
scroll-v5.8.38
or higher. - Use
--scroll
instead of--scroll-sepolia
. - Mainnet requires a fully synced Ethereum Mainnet RPC for the
--l1.endpoint
flag. - Bootnode setup differs (5 default + 2 optional dedicated ones).
Prerequisites
Staying Up-to-Date
Keep an eye on https://github.com/scroll-tech/go-ethereum/releases for new node releases.
- Go to https://github.com/scroll-tech/go-ethereum
- Click on “Watch”, “Custom”, and make sure that “Releases” is selected.
We recommend using the latest release at https://github.com/scroll-tech/go-ethereum/releases.
Naming Conventions
The preferred network name is Scroll
or scroll
. If you operate a user-facing service (e.g. public RPC endpoint), please consider using this name.
Hardware Requirements
Recommended
- Machine comparable to AWS
t3.2xlarge
instance. - 4TB gp3 SSD storage.
Docker
This section assumes you are familiar with Docker and have Docker and Docker Compose installed and running.
L1 RPC Node
You will need access to a fully-synced Ethereum Mainnet RPC endpoint before running l2geth
. You can maintain your own node or choose to use a 3rd-party provider that supports the standard Ethereum RPC APIs. The remainder of the article assumes that you have access to an L1 node’s HTTP RPC API at L2GETH_L1_ENDPOINT
.
Example: L2GETH_L1_ENDPOINT="https://my-node.com:8545"
Build and Run Using Docker with Snapshot
Download L2geth
Download the latest l2geth :
docker pull scrolltech/l2geth:latest
Download the Snapshot
SNAPSHOT_URL = https://scroll-geth-snapshot.s3.us-west-2.amazonaws.com/mpt/latest.tar
- Create a new folder for the snapshot
mkdir l2geth
- Go to the created folder
push l2geth
- Download the snapshot
wget $SNAPSHOT_URL
- unarchive the snapshot
tar -xf latest.tar
Run L2geth
- Go to the snapshot folder
cd l2geth
- In the l2geth folder, setup the docker-compose.yaml config Insert your config in the yaml file and save it, recommended config would be :
services: l2geth: image: scrolltech/l2geth:latest container_name: l2geth-docker stop_signal: SIGINT stop_grace_period: 60s restart: "unless-stopped" environment: - CHAIN_ID=534352 - RUST_LOG="info" volumes: - 'l2geth/data:/volume/l2geth/data' ports: - 8545:8545 - 8546:8546 - 6060:6060 - 30303:30303 - 30303:30303/udp
command: --scroll --scroll-mpt --snapshot=false --metrics --pprof.addr 0.0.0.0 --pprof.port 6060 --datadir /volume/l2geth/data --gcmode archive --http --http.addr 0.0.0.0 --http.port 8545 --http.api eth,net,web3,debug,scroll --cache.noprefetch --l1.endpoint "${Your l1 endpoint}" --da.blob.blobscan "${Your blobscan endpoint}" --da.blob.beaconnode "${Your beaconnode endpoint}" --cache.snapshot=0 logging: driver: "json-file" options: max-size: "100m" max-file: "1"
- Run the docker
docker compose up -d
- In a separate shell, you can now attach to
l2geth
.
$ docker exec -it l2geth-docker geth attach "/volume/l2geth-datadir/geth.ipc"
> admin.peers.length 5
> eth.blockNumber 10000
Interacting with the L2geth Container
- Check logs:
docker logs --tail 10 -f l2geth-docker
- Stop the container:
docker stop l2geth-docker
- Fetch metrics:
curl http://localhost:6060/debug/metrics/prometheus
Configuration Reference
- SCROLL_L2_CHAIN_ID_L2=
534352
- SCROLL_L2_NETWORK_ID_L2=
534352
- SCROLL_L2_GENESIS_HASH=
0xbbc05efd412b7cd47a2ed0e5ddfcf87af251e414ea4c801d78b6784513180a80
Bootnode list:
enode://c6ac91f43df3d63916ac1ae411cdd5ba249d55d48a7bec7f8cd5bb351a31aba437e5a69e8a1de74d73fdfeba8af1cfe9caf9846ecd3abf60d1ffdf4925b55b23@54.186.123.248:30303enode://fdcc807b5d1353f3a1e98b90208ce6ef1b7d446136e51eaa8ad657b55518a2f8b37655e42375d61622e6ea18f3faf9d070c9bbdf012cf5484bcbad33b7a15fb1@44.227.91.206:30303enode://6beb5a3efbb39be73d17630b6da48e94c0ce7ec665172111463cb470197b20c12faa1fa6f835b81c28571277d1017e65c4e426cc92a46141cf69118ecf28ac03@44.237.194.52:30303enode://7cf893d444eb8e129dca0f6485b3df579911606e7c728be4fa55fcc5f155a37c3ce07d217ccec5447798bde465ac2bdba2cb8763d107e9f3257e787579e9f27e@52.35.203.107:30303enode://c7b2d94e95da343db6e667a01cef90376a592f2d277fbcbf6e9c9186734ed8003d01389571bd10cdbab7a6e5adfa6f0c7b55644d0db24e0b9deb4ec80f842075@54.70.236.187:30303enode://a28f9c5a8f6ed2a5063210a1253ddba9b8b48434e4700198ec8c6e687753dc0eba6dcef4fbbe8a6aeef2079884c2d85ca0bffcab8ec826111576a2cffe7a3266@44.230.97.163:30303enode://0bb5919853cb7cfc302d3c7ac266890cc8f3c67cce7e8fa8d45c3714237fbed395a7b964de131617cf10903774a8ef59d89c002136c2dedad9ef8bd8eddc3ef7@52.36.234.198:30303
Genesis json file can be found here
Troubleshooting
- The node (APIs, geth console, etc) will not be responsive until all the L1 messages have been synced.
- However, the derivation pipeline is already started during the initial sync phase, which can be seen through
L1 sync progress [...]
logs. - For Scroll Sepolia it might take a little longer (10-20mins) for the first
L1 sync progress [...]
logs to appear as the L1 blocks are more sparse at the beginning.
You should see something like this shortly after starting:
INFO [09-18|13:41:34.039] Starting L1 message sync service latestProcessedBlock=20,633,529WARN [09-18|13:41:34.551] Running initial sync of L1 messages before starting l2geth, this might take a while...INFO [09-18|13:41:45.249] Syncing L1 messages processed=20,634,929 confirmed=20,777,179 collected=71 progress(%)=99.315INFO [09-18|13:41:55.300] Syncing L1 messages processed=20,637,029 confirmed=20,777,179 collected=145 progress(%)=99.325INFO [09-18|13:42:05.400] Syncing L1 messages processed=20,638,329 confirmed=20,777,179 collected=220 progress(%)=99.332INFO [09-18|13:42:15.610] Syncing L1 messages processed=20,640,129 confirmed=20,777,179 collected=303 progress(%)=99.340INFO [09-18|13:42:24.324] L1 sync progress "blockchain height"=1000 "block hash"=a28c48..769cee root=174edb..9d9fbdINFO [09-18|13:42:25.555] Syncing L1 messages processed=20,641,529 confirmed=20,777,179 collected=402 progress(%)=99.347
Common Errors
If you run l2geth
in Docker and get this error on MacOS, you need to add the /volume
directory to the list of shared paths in Docker Desktop settings.
- Click the Docker icon in the macOS menu bar, then click Settings.
- Go to the Resources tab.
- Click on File Sharing.
- Click the ”+” (plus) button to add a new shared folder.
- Navigate to the root directory, select the
volume
folder, and click Open. - Click Apply & Restart for the changes to take effect.
The genesis config format changed starting at version scroll-v3.1.3
. You can fix this error in two ways:
- Run
l2geth
with the--scroll
flag. This will automatically import the up-to-date genesis config. - Alternatively, you can download the latest genesis.json , and run
l2geth --datadir "./l2geth-datadir" init "./genesis.json"
before running the node. This command will import the updated genesis config. Note: Your local database will remain intact.
If DockerHub does not have the container version required by your system, you can pass --platform linux/amd64
to each Docker command. For better performance, we recommend that you build the image for your platform or Build and Run From Source .
Please make sure your l1 endpoint is working as expected
Please add working —da.blob.blobscan and —da.blob.beaconnode endpoints
The issue could be caused by :
- Disk issue (busy or out of space) Please increase disk space or check why it is busy
- You recently shut down or restart your machine, mpt-trie has a graceful shutdown issue
Add flag
--cache.snapshot=0
and--snapshot=false
to disable snapshot