Skip to content

Commit d95e959

Browse files
authored
feat: sequencer migration (#338)
* add initial sequencer migration script and readme * add test for sequencer migration script * add l2geth revert script * add more documentation * simplify scripts and remove duplicate code * address review comments * simplify more * add simple switch to l2geth script * add Dockerfile and add more usage documentation * push to Dockerhub
1 parent fbfd7c8 commit d95e959

File tree

10 files changed

+841
-1
lines changed

10 files changed

+841
-1
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Sequencer Migration Docker
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
release:
8+
types: [published]
9+
10+
jobs:
11+
build-and-push:
12+
runs-on:
13+
group: scroll-reth-runner-group
14+
permissions: {}
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v5
19+
with:
20+
persist-credentials: false
21+
22+
- name: Extract docker metadata
23+
id: meta
24+
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
25+
with:
26+
images: scrolltech/sequencer-migration
27+
tags: |
28+
type=ref,event=tag,enable=${{ github.event_name == 'push' }}
29+
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
30+
flavor: |
31+
latest=false
32+
33+
- name: Login to Docker Hub
34+
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
35+
with:
36+
username: ${{ secrets.DOCKERHUB_USERNAME }}
37+
password: ${{ secrets.DOCKERHUB_TOKEN }}
38+
39+
- name: Build and push Docker image
40+
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
41+
with:
42+
context: sequencer-migration
43+
file: sequencer-migration/Dockerfile
44+
push: true
45+
tags: ${{ steps.meta.outputs.tags }}
46+
labels: ${{ steps.meta.outputs.labels }}

sequencer-migration/Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM ghcr.io/foundry-rs/foundry:stable
2+
3+
USER root
4+
RUN apt-get update && apt-get install -y \
5+
jq
6+
7+
WORKDIR /migration
8+
COPY . .
9+
10+
RUN chmod +x migrate-sequencer.sh \
11+
revert-l2geth-to-block.sh \
12+
switch-to-l2geth.sh
13+
14+
# Set default environment variables (can be overridden at runtime)
15+
ENV L2GETH_RPC_URL=http://host.docker.internal:8547
16+
ENV L2RETH_RPC_URL=http://host.docker.internal:8545
17+
18+
USER foundry
19+
20+
# Auto-source common functions when bash starts
21+
RUN echo 'source /migration/common-functions.sh' >> /home/foundry/.bashrc
22+
23+
# Default to interactive bash shell with RC file loaded
24+
CMD ["/bin/bash", "-l"]

sequencer-migration/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Scroll Sequencer Migration
2+
This module contains documentation and scripts for Scroll's sequencer migration from `l2geth` to rollup node (RN) aka `l2reth`.
3+
4+
### Risks
5+
We want to minimize risks and minimize service disruption. For this we need to consider following risks:
6+
- invalid L2 blocks produced
7+
- L2 reorg (e.g. different blocks issued at same L2 block height)
8+
- L1 messages skipped/reverted
9+
- general service interruption
10+
11+
## Migration Procedure
12+
13+
To instill confidence we will do many repeated transitions from `l2geth` -> `l2reth` -> `l2geth` with the time that `l2reth` sequences increasing.
14+
15+
The high-level flow of the transition will look like this:
16+
1. `l2geth` is sequencing currently
17+
2. Turn off `l2geth` sequencing
18+
3. Get block height of `l2geth`
19+
4. Wait until `l2reth` has same block height
20+
5. Turn on `l2reth` sequencing
21+
6. Wait until `l2reth` has sequenced until block X or for some time
22+
7. Turn off `l2reth` sequencing
23+
8. Wait until `l2geth` has same block height
24+
9. Turn on `l2geth` sequencing
25+
26+
## Usage
27+
Make sure the `L2RETH_RPC_URL` and `L2GETH_RPC_URL` env variables are properly configured. Simply run the script and follow the instructions.
28+
29+
```bash
30+
./migrate-sequencer.sh <blocks_to_produce>
31+
./revert-l2geth-to-block.sh <block_number>
32+
./switch-to-l2geth.sh
33+
34+
# make common functions available on bash
35+
source common-functions.sh
36+
37+
start_l2geth_mining
38+
get_block_info $L2GETH_RPC_URL
39+
[...]
40+
```
41+
42+
### Testing locally
43+
To test locally run the test `docker_test_migrate_sequencer` and execute the `migrate-sequencer.sh` script.
44+
```bash
45+
# this test runs for ~60 seconds and starts with l2geth sequencing and expects all nodes to reach the same block at block number 120.
46+
RUST_LOG=info,docker-compose=off cargo test --package tests --test migrate_sequencer -- docker_test_migrate_sequencer --exact --show-output
47+
48+
source local.env
49+
./migrate-sequencer.sh <blocks_to_produce>
50+
51+
# if necessary, reset l2geth block height and start sequencing on l2geth.
52+
./revert-l2geth-to-block.sh <block_number>
53+
```
54+
55+
**Simulating failure case**:
56+
- To simulate the case where `l2reth` produces invalid blocks we can adjust to `--builder.gaslimit=40000000` in `launch_rollup_node_sequencer.bash`. This will produce a block with a too big jump of the gas limit and `l2geth` will reject it. In a simulation we can then "revert" `l2geth` to its latest block and start sequencing on `l2geth` again.
57+
- Continuing on the above case we can fabricate a L2 reorg by simply resetting to any previous block. For all `l2geth` nodes the reorg will be shallow (ie before the invalid `l2reth` blocks) and for `l2reth` it will be deeper (ie all `l2reth` produced blocks + reset to previous block).
58+
59+
### Running with Docker
60+
```bash
61+
docker run -it --rm sequencer-migration:latest
62+
63+
# then just use the scripts as before
64+
./migrate-sequencer.sh <blocks_to_produce>
65+
66+
# or call any of the common functions
67+
start_l2geth_mining
68+
get_block_info $L2GETH_RPC_URL
69+
[...]
70+
```
71+
72+
If running on Linux you might need to specify `-e L2GETH_RPC_URL=http://your-l2geth:8547 -e L2RETH_RPC_URL=http://your-l2reth:8545` as the default URLs might not work.

0 commit comments

Comments
 (0)