Skip to content

Commit e4c73b4

Browse files
authored
Merge pull request #411 from scroll-tech/develop
feat: add docs about L1 follower node (#374)
2 parents 3dc9127 + 606df5a commit e4c73b4

File tree

1 file changed

+166
-1
lines changed

1 file changed

+166
-1
lines changed

src/content/docs/en/developers/guides/running-a-scroll-node.mdx

+166-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ For most developers, using [our official RPC endpoint](/en/developers/developer-
1919

2020
We recommend using the latest release at https://github.com/scroll-tech/go-ethereum/releases. The required version for Scroll Mainnet is `scroll-v5.5.0` or higher, and for Scroll Sepolia it is `scroll-v5.4.2` or higher. If you'd like to keep up with new node releases, go to https://github.com/scroll-tech/go-ethereum, click on **Watch**, **Custom**, and make sure that **Releases** is selected.
2121

22-
For the remainder of this guide, `VERSION` will denote the version tag. For example, `scroll-v5.7.0`.
22+
For the remainder of this guide, `VERSION` will denote the version tag. For example, `scroll-v5.8.0`.
2323

2424
### Hardware Requirements
2525

@@ -139,6 +139,171 @@ Running the node in Docker might have a significant impact on node performance.
139139
- Check logs: `docker logs --tail 10 -f l2geth-docker`
140140
- Stop the container: `docker stop l2geth-docker`
141141

142+
---
143+
144+
## Run L2geth in L1 Follower Mode
145+
146+
<Aside type="tip">
147+
An l2geth node running in L1 follower mode does not participate in the L2 peer-to-peer network.
148+
Instead, it follows finalized blocks on L1, and derives the L2 chain and state by decoding and executing data from L1 DA (blobs).
149+
This mode guarantees that nodes can always reconstruct the L2 state, even if the data is never published on the L2 peer-to-peer network.
150+
</Aside>
151+
152+
Run `l2geth` with the `--da.sync` flag.
153+
Provide blob APIs and beacon node by configuring one or more of the following flags:
154+
- `--da.blob.beaconnode "<L1 beacon node>"` (recommended, if beacon node supports historical blobs)
155+
- `--da.blob.blobscan "https://api.blobscan.com/blobs/"` `--da.blob.blocknative "https://api.ethernow.xyz/v1/blob/"` for Mainnet
156+
- `--da.blob.blobscan "https://api.sepolia.blobscan.com/blobs/"` for Sepolia.
157+
158+
Strictly speaking a single blob provider is sufficient.
159+
However, configuring multiple providers can help avoid reliability issues.
160+
Using a beacon node with historical blob data is the recommended option (can be in addition to the Blobscan and Blocknative APIs).
161+
162+
163+
### Mainnet
164+
```bash
165+
./build/bin/geth --scroll \
166+
--datadir "tmp/mainnet-l2geth-datadir" \
167+
--gcmode archive \
168+
--http --http.addr "0.0.0.0" --http.port 8545 --http.api "eth,net,web3,debug,scroll" \
169+
--da.sync=true \
170+
--da.blob.blobscan "https://api.blobscan.com/blobs/" --da.blob.blocknative "https://api.ethernow.xyz/v1/blob/" \
171+
--da.blob.beaconnode "<L1 beacon node>" \
172+
--l1.endpoint "<L1 RPC node>" \
173+
--verbosity 3
174+
```
175+
176+
177+
### Sepolia
178+
```bash
179+
./build/bin/geth --scroll-sepolia \
180+
--datadir "tmp/sepolia-l2geth-datadir" \
181+
--gcmode archive \
182+
--http --http.addr "0.0.0.0" --http.port 8545 --http.api "eth,net,web3,debug,scroll" \
183+
--da.sync=true \
184+
--da.blob.blobscan "https://api.sepolia.blobscan.com/blobs/" \
185+
--da.blob.beaconnode "<L1 beacon node>" \
186+
--l1.endpoint "<L1 RPC node>" \
187+
--verbosity 3
188+
```
189+
190+
A full sync will take about 2 weeks for Scroll mainnet and 2-3 days for Scroll Sepolia depending on the speed of the RPC node, beacon node and the local machine.
191+
Progress is reported as follows for every 1000 blocks applied:
192+
193+
```bash
194+
INFO [08-01|16:44:42.173] L1 sync progress blockchain height=87000 block hash=608eec..880ebd root=218215..9a58a2
195+
```
196+
197+
198+
### Troubleshooting
199+
- The node (APIs, geth console, etc) will not be responsive until all the L1 messages have been synced.
200+
- However, the derivation pipeline is already started during the initial sync phase, which can be seen through `L1 sync progress [...]` logs.
201+
- 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.
202+
203+
You should see something like this shortly after starting:
204+
```bash
205+
INFO [09-18|13:41:34.039] Starting L1 message sync service latestProcessedBlock=20,633,529
206+
WARN [09-18|13:41:34.551] Running initial sync of L1 messages before starting l2geth, this might take a while...
207+
INFO [09-18|13:41:45.249] Syncing L1 messages processed=20,634,929 confirmed=20,777,179 collected=71 progress(%)=99.315
208+
INFO [09-18|13:41:55.300] Syncing L1 messages processed=20,637,029 confirmed=20,777,179 collected=145 progress(%)=99.325
209+
INFO [09-18|13:42:05.400] Syncing L1 messages processed=20,638,329 confirmed=20,777,179 collected=220 progress(%)=99.332
210+
INFO [09-18|13:42:15.610] Syncing L1 messages processed=20,640,129 confirmed=20,777,179 collected=303 progress(%)=99.340
211+
INFO [09-18|13:42:24.324] L1 sync progress "blockchain height"=1000 "block hash"=a28c48..769cee root=174edb..9d9fbd
212+
INFO [09-18|13:42:25.555] Syncing L1 messages processed=20,641,529 confirmed=20,777,179 collected=402 progress(%)=99.347
213+
```
214+
215+
#### Temporary Errors
216+
217+
Especially at the beginning some errors like below might appear in the console.
218+
This is expected, as the pipeline relies on the L1 messages but in case they are not synced fast enough such an error might pop up.
219+
The chain derivation will continue once the L1 messages are available.
220+
```
221+
WARN [09-18|13:52:25.843] syncing pipeline step failed due to temporary error, retrying err="temporary: failed to process logs to DA, error: failed to get commit batch da: 7, err: failed to get L1 messages for v0 batch 7: EOF: <nil>"
222+
```
223+
224+
### Limitations
225+
226+
L1 follower nodes can reproduce the correct `state root` of L2 blocks.
227+
However, currently the derived `block hash` will not match the one seen on L2 follower nodes or Scrollscan.
228+
This is due to the fact that currently the header fields `difficulty` and `extraData` are not stored on DA but these fields are utilized by [Clique consensus](https://eips.ethereum.org/EIPS/eip-225) which is used by the Scroll protocol.
229+
This will be fixed in a future upgrade.
230+
231+
To verify the locally created `state root` against mainnet, we can do the following:
232+
233+
```bash
234+
# query local block info
235+
curl localhost:8545 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getHeaderByNumber","params":["0x2AF8"],"id":0}' | jq
236+
237+
# query mainnet block info
238+
curl https://rpc.scroll.io -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_getHeaderByNumber","params":["0x2AF8"],"id":0}' | jq
239+
```
240+
241+
By comparing the headers we can most importantly see that **`state root` , `receiptsRoot` and everything that has to do with the state match**.
242+
However, the following fields will be different:
243+
244+
- `difficulty` and therefore `totalDifficulty`
245+
- `extraData`
246+
- `size` due to differences in header size
247+
- `hash` and therefore `parentHash`
248+
249+
Example local output for block 11000:
250+
251+
```bash
252+
{
253+
"jsonrpc": "2.0",
254+
"id": 0,
255+
"result": {
256+
"difficulty": "0xa",
257+
"extraData": "0x0102030405060708",
258+
"gasLimit": "0x989680",
259+
"gasUsed": "0xa410",
260+
"hash": "0xf3cdafbe35d5e7c18d8274bddad9dd12c94b83a81cefeb82ebb73fa799ff9fcc",
261+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
262+
"miner": "0x0000000000000000000000000000000000000000",
263+
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
264+
"nonce": "0x0000000000000000",
265+
"number": "0x2af8",
266+
"parentHash": "0xde244f7e8bc54c8809e6c2ce65c439b58e90baf11f6cf9aaf8df33a827bd01ab",
267+
"receiptsRoot": "0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4",
268+
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
269+
"size": "0x252",
270+
"stateRoot": "0x0f387e78e4a7457a318c7bce7cde0b05c3609347190144a7e105ef05194ae218",
271+
"timestamp": "0x6526db8e",
272+
"totalDifficulty": "0x1adb1",
273+
"transactionsRoot": "0x6a81c9342456693d57963883983bba024916f4d277392c9c1dc497e3518a78e3"
274+
}
275+
}
276+
```
277+
278+
Example remote output:
279+
280+
```bash
281+
{
282+
"id": 0,
283+
"jsonrpc": "2.0",
284+
"result": {
285+
"difficulty": "0x2",
286+
"extraData": "0xd883050000846765746888676f312e31392e31856c696e7578000000000000009920319c246ec8ae4d4f73f07d79f68b2890e9c2033966efe5a81aedddae12875c3170f0552f48b7e5d8e92ac828a6008b2ba7c5b9c4a0af1692337bbdc792be01",
287+
"gasLimit": "0x989680",
288+
"gasUsed": "0xa410",
289+
"hash": "0xb7848d5b300247d7c33aeba0f1b33375e1cb3113b950dffc140945e9d3d88d58",
290+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
291+
"miner": "0x0000000000000000000000000000000000000000",
292+
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
293+
"nonce": "0x0000000000000000",
294+
"number": "0x2af8",
295+
"parentHash": "0xa93e6143ab213a044eb834cdd391a6ef2c818de25b04a3839ee44a75bd28a2c7",
296+
"receiptsRoot": "0xd95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4",
297+
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
298+
"size": "0x2ab",
299+
"stateRoot": "0x0f387e78e4a7457a318c7bce7cde0b05c3609347190144a7e105ef05194ae218",
300+
"timestamp": "0x6526db8e",
301+
"totalDifficulty": "0x55f1",
302+
"transactionsRoot": "0x6a81c9342456693d57963883983bba024916f4d277392c9c1dc497e3518a78e3"
303+
}
304+
}
305+
```
306+
142307
---
143308
## Configuration Reference
144309

0 commit comments

Comments
 (0)