# L2 Archive Node Setup guide

{% hint style="info" %}
If you're an existing operator looking to migrate your your node from goerli to sepolia, skip to [migrating the L2](#migrating-the-l2)
{% endhint %}

## **Step 1: Install Software Dependencies**

Ensure that the following software dependencies are installed and meet the specified version requirements. Use the provided version check commands to confirm:

## **Step 2: Set-up L2 node via set-up script**

{% hint style="info" %}
As of ecotone upgrade, this script is outdated, we're working to update it to support the latest version. Meanwhile please continue with rest of the guide below, skipping Step 2.&#x20;
{% endhint %}

If you want to use a script that will automatically download the snapshot and set-up and start L2 node follow this step and skip steps 3-8. If you want to manually download the snapshot and set-up L2 node, then skip this step and go to step 3.

Download the scripts to set-up L2:

```bash
git clone https://github.com/kaleidoscope-blockchain/l2-set-up.git
```

The folder l2-set-up, will have script run that starts the set-up process. The run script takes two arguments,

1. chain-name - "base" or "optimism". Currently only base and optimism L2 are supported
2. L1\_RPC\_URL - Give the Sepolia RPC URL that you use to connect to L1

For example,

```bash
cd l2-set-up
./run optimism https://eth-sepolia.g.alchemy.com/v2/hhTXZSBtLsbNN-wXWpErThgYi9sNNKTP
```

The script will start a tmux shell with name "set-up-l2" that will download the snapshot. You can connect to tmux shell via the command,&#x20;

```bash
tmux a -t set-up-l2
```

Once the download of snapshot is done, tmux shell is terminated. After download of snapshot, geth and node clients are started in tmux shells with names, "optimism-geth" and "optimism-node" if optimism is selected, else if base is selected the tmux shell names will be "base-geth" and "base-node". To connect to a tmux shell, run the command

```bash
tmux a -t shell-name
```

If you follow step 2, then skip steps 3-8 and go to step 9

## **Step 3: Download the Snapshot**

To initiate the Watchtower environment, begin by downloading the latest available snapshot hosted by WitnessChain as a part of Light configuration for L2 node setup. Use the following commands:

For `op-sepolia:`

```shell
wget $(curl https://witnesschain-l2-snapshots.s3.amazonaws.com/op-latest)
```

For `base-sepolia:`

```shell
wget $(curl https://witnesschain-l2-snapshots.s3.amazonaws.com/base-latest)

```

{% hint style="info" %}
Consider using a download acceleration tool like [aria2c](https://aria2.github.io/) for faster downloads.&#x20;

An example for downloading base snapshot:

&#x20;`aria2c -s16 -x16` $(curl <https://witnesschain-l2-snapshots.s3.amazonaws.com/op-latest>)
{% endhint %}

{% hint style="success" %}

#### Medium **configuration for L2 node setup**

Alternatively operators can consider publicly posted snapshots to start their node syncs. These snapshots are not hosted by WitnessChain, hence their availability and recency is subject to L2 chains publishing it themselves.

`Note that WitnessChain highly encourages operators to utilize the snapshot hosted by us for a faster node setup and save days worth of time and compute on the same. That said, we're committed to keeping the watchtowers as trustless and neutral entities, hence the operators can feel free to choose the source of trust for their snapshot.`
{% endhint %}

## Step 4: Building the Optimism monorepo (Rollup Node/op-node) <a href="#id-3-building-the-optimism-monorepo-rollup-node-op-node" id="id-3-building-the-optimism-monorepo-rollup-node-op-node"></a>

### Clone the optimism monorepo and cd into it

```shell
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
```

### Checkout to the release branch (`op-node/v1.7.0` as of Mar 17, 2024)

```shell
git checkout op-node/v1.7.0
```

### Install nodejs dependencies and build nodejs packages

```shell
pnpm install 
pnpm build
```

### Build op-node

```shell
make op-node
```

## **Step 5: Build Execution Client (op-geth)**

Clone the op-geth repo, switch to the release branch (e.g., `v1.101308.0` as of Feb 24, 2024 ), and build op-geth:

```shell
git clone https://github.com/ethereum-optimism/op-geth.git
cd op-geth
git checkout v1.101308.0
make geth
```

## **Step 6: Create a JWT Secret**

Generate a 32-byte hex string as a shared secret for communication between op-node and op-geth:

```sh
openssl rand -hex 32 > jwt.txt
```

## Step 7: Configure and Start op-geth <a href="#id-6-configure-and-start-op-geth" id="id-6-configure-and-start-op-geth"></a>

{% hint style="info" %}
It's generally easier to start `op-geth` before starting `op-node`. You can still start `op-geth` without yet running `op-node`, but the `op-geth` instance will simply not receive any blocks until `op-node` is started.
{% endhint %}

Navigate to the op-geth directory, copy the JWT secret, and start op-geth:

```shell
# cd to the op-geth directory

cp /path/to/jwt.txt .

```

Unzip snapshot from step 1 in `/datadir/` in the same directory where you built `op-geth`. The final path for snapshot would look something like this

`/path/to/op-geth/datadir/geth`

<pre><code><strong># Unzip the snapshot from Step 1 in /datadir/ into 
</strong><strong># the same directory where you built op-geth
</strong># Example path for snapshot: /path/to/op-geth/datadir/geth
</code></pre>

{% hint style="danger" %}
if your path after snapshot unzipping and moving does not look as above, please either rename any directory required for the same or update the value of `--datadir` flag to point to path of the snapshot in the script below.
{% endhint %}

Create the following scripts in the same directory where you built `op-geth,`based on the L2 chain you would like to setup

* `run-geth-optimism.sh` for `op-sepolia` or&#x20;
* `run-geth-base.sh` for `base-sepolia`

{% hint style="info" %}
chmod +x for all the below mentioned scripts, if you run into permission issues
{% endhint %}

{% code title="run-geth-optimism.sh" %}

```shell
#!/usr/bin/bash

SEQUENCER_URL=https://sepolia-sequencer.optimism.io/


sudo ./build/bin/geth \
  --ws \
  --ws.port=8546 \
  --ws.addr=0.0.0.0 \
  --ws.origins="*" \
  --http \
  --http.port=8545 \
  --http.addr=0.0.0.0 \
  --http.vhosts="*" \
  --http.corsdomain="*" \
  --http.api=web3,debug,eth,net,engine \
  --authrpc.addr=localhost \
  --authrpc.jwtsecret=./jwt.txt \
  --authrpc.port=8551 \
  --authrpc.vhosts="*" \
  --datadir=./datadir \
  --verbosity=3 \
  --rollup.disabletxpoolgossip=true \
  --rollup.sequencerhttp=$SEQUENCER_URL \
  --nodiscover \
  --syncmode=full \
  --gcmode archive \
  --maxpeers=0 \
  --rollup.halt=major \
  --op-network=op-sepolia

```

{% endcode %}

{% code title="run-geth-base.sh" %}

```shell
#!/usr/bin/bash

SEQUENCER_URL=https://sepolia-sequencer.base.org

sudo ./build/bin/geth \
  --ws \
  --ws.port=8546 \
  --ws.addr=0.0.0.0 \
  --ws.origins="*" \
  --ws.api=debug,eth,net,engine \
  --http \
  --http.port=8545 \
  --http.addr=0.0.0.0 \
  --http.vhosts="*" \
  --http.corsdomain="*" \
  --http.api=web3,debug,eth,net,engine \
  --authrpc.addr=localhost \
  --authrpc.jwtsecret=./jwt.txt \
  --authrpc.vhosts="*" \
  --datadir=./datadir \
  --verbosity=3 \
  --rollup.disabletxpoolgossip=true \
  --rollup.sequencerhttp=$SEQUENCER_URL \
  --rollup.halt=major \
  --nodiscover \
  --syncmode=full \
  --gcmode=archive \
  --maxpeers=100 \
  --op-network=base-sepolia

```

{% endcode %}

{% hint style="info" %}
It is recommended you use tmux to run this in a detached background process
{% endhint %}

The following commands will start `op-geth` with our recommended configuration. The JSON-RPC API will become available on port 8545. Refer to the `op-geth` [configuration documentation](https://docs.optimism.io/builders/node-operators/management/configuration#op-geth) for more detailed information about available options.

for `op-sepolia`:

<pre class="language-shell"><code class="lang-shell"><strong>./run-geth-optimism.sh
</strong></code></pre>

for `base-sepolia`:

```shell
./run-geth-base.sh
```

## Step 8: Configure and Start op-node <a href="#id-6-configure-and-start-op-geth" id="id-6-configure-and-start-op-geth"></a>

Navigate to the op-node directory, copy the JWT secret, and start op-node:

```shell
# cd to the op-node directory 

# Both op-geth and op-node need to use the same JWT secret. 
# Copy the JWT secret you generated in a previous step into the op-node directory.

cp /path/to/jwt.txt .

```

Create the relevant script in the same directory where you built `op-node.` Based on your network `run-node-optimism.sh` for `op-sepolia` or `run-node-base.sh` for `base-sepolia`&#x20;

{% hint style="info" %}
chmod +x for all the below mentioned scripts, if you run into permission issues
{% endhint %}

{% code title="run-node-optimism.sh" %}

```shell
#!#!/usr/bin/bash

sudo bin/op-node --l1=<L1_RPC_URL> \
        --l1.beacon=<L1_BEACON_NODE_URL> \
        --l2=ws://localhost:8551 \
        --network=op-sepolia \
        --rollup.halt=major \
        --rollup.load-protocol-versions=true \
        --rpc.addr=0.0.0.0 \
        --rpc.port=9545 \
        --l2.jwt-secret=./jwt.txt

```

{% endcode %}

{% code title="run-node-base.sh" %}

```shell
#!/usr/bin/bash

sudo bin/op-node \
  --l1=<L1_RPC_URL> \
  --l1.beacon=<L1_BEACON_NODE_URL> \
  --l2=ws://localhost:8551 \
  --rpc.addr=0.0.0.0 \
  --rpc.port=9545 \
  --l2.jwt-secret=./jwt.txt \
  --network=base-sepolia \
  --rollup.halt=major \
  --rollup.load-protocol-versions=true

```

{% endcode %}

In the script, replace `<L1_RPC_URL>` with your sepolia (L1) RPC url and `<L1_BEACON_NODE_URL>` with url of corresponding beacon node.

{% hint style="info" %}
If you don't currently have access to a beacon node, you can setup any of the available software for it, including *Lighthouse*, *Prysm* etc. using their docs. One such guide can be found here to setup a P*rysm* node:\
<https://docs.prylabs.network/docs/install/install-with-script>
{% endhint %}

{% hint style="info" %}
Some L1 nodes, like Erigon, do not support the `eth_getProof` RPC method that the `op-node` uses to load L1 data for certain processing steps. If you are using an L1 node that does not support `eth_getProof`, you will need to include the `--l1.trustrpc` flag when starting `op-node`. You’ll have to modify the script with the same. Note that this flag will cause `op-node` to trust the L1 node to provide correct data as it will no longer be able to independently verify the data it receives.
{% endhint %}

{% hint style="info" %}
&#x20;It is recommended you use tmux to run this in a detached background process
{% endhint %}

Use the following command to start `op-node` with the recommended configuration. Refer to the `op-node` [configuration documentation](https://docs.optimism.io/builders/node-operators/management/configuration#op-node) for more detailed information about available options.

for `op-sepolia`:

```shell
./run-node-optimism.sh
```

for `base-sepolia`:

```shell
./run-node-base.sh
```

## 9. Post Setup

### Synchronization <a href="#synchronization" id="synchronization"></a>

Once you've started `op-geth` and `op-node` you should see the two begin to communicate with each other and synchronize the L2 chain. Initial synchronization can take several hours to complete.

During this time, you will initially observe `op-node` deriving blocks from Sepolia without sending these blocks to `op-geth`. This means that `op-node` is requesting blocks from Sepolia one-by-one and determining the corresponding L2 blocks that were published to Sepolia. You should see logs like the following from `op-node`:

```
INFO [06-26|13:31:20.389] Advancing bq origin                      origin=17171d..1bc69b:8300332 originBehind=false

```

Once the `op-node` has derived enough blocks from Sepolia, it will begin sending these blocks to `op-geth`. You should see logs like the following from `op-node`:

```
INFO [06-26|14:00:59.460] Sync progress                            reason="processed safe block derived from L1" l2_finalized=ef93e6..e0f367:4067805 l2_safe=7fe3f6..900127:4068014 l2_unsafe=7fe3f6..900127:4068014 l2_time=1,673,564,096 l1_derived=6079cd..be4231:8301091
INFO [06-26|14:00:59.460] Found next batch                         epoch=8e8a03..11a6de:8301087 batch_epoch=8301087 batch_timestamp=1,673,564,098
INFO [06-26|14:00:59.461] generated attributes in payload queue    txs=1  timestamp=1,673,564,098
INFO [06-26|14:00:59.463] inserted block                           hash=e80dc4..72a759 number=4,068,015 state_root=660ced..043025 timestamp=1,673,564,098 parent=7fe3f6..900127 prev_randao=78e43d..36f07a fee_recipient=0x4200000000000000000000000000000000000011 txs=1  update_safe=true
```

You should then also begin to see logs like the following from `op-geth`:

```
INFO [06-26|14:02:12.974] Imported new potential chain segment     number=4,068,194 hash=a334a0..609a83 blocks=1         txs=1         mgas=0.000  elapsed=1.482ms     mgasps=0.000   age=5mo2w20h dirty=2.31MiB
INFO [06-26|14:02:12.976] Chain head was updated                   number=4,068,194 hash=a334a0..609a83 root=e80f5e..dd06f9 elapsed="188.373µs" age=5mo2w20h
INFO [06-26|14:02:12.982] Starting work on payload                 id=0x5542117d680dbd4e
```

### Tracking the sync progress <a href="#tracking-the-sync-progress" id="tracking-the-sync-progress"></a>

You can run the following script, which will, over a minute, estimate the current sync speed and based on it the expected time for the sync to complete. The result is printed on the terminal, though remember that it is only an estimate.&#x20;

Create a file `run-estimate.sh` and paste the following code in it:

{% hint style="info" %}
chmod +x for all the below mentioned scripts, if you run into permission issues
{% endhint %}

{% code title="run-estimate.sh" %}

```shell
#!/usr/bin/bash

export ETH_RPC_URL=http://localhost:8545
CHAIN_ID=`cast chain-id`
echo Chain ID: $CHAIN_ID
echo Please wait

if [ $CHAIN_ID -eq 11155420 ]; then
  L2_URL=https://sepolia.optimism.io
fi

if [ $CHAIN_ID -eq 84532 ]; then
  L2_URL=https://sepolia.base.org
fi

T0=`cast block-number --rpc-url $ETH_RPC_URL` ; sleep 60 ; T1=`cast block-number --rpc-url $ETH_RPC_URL`
PER_MIN=`expr $T1 - $T0`
echo Blocks per minute: $PER_MIN


if [ $PER_MIN -eq 0 ]; then
    echo Not synching
    exit;
fi

# During that minute the head of the chain progressed by thirty blocks
PROGRESS_PER_MIN=`expr $PER_MIN - 30`
echo Progress per minute: $PROGRESS_PER_MIN


# How many more blocks do we need?
HEAD=`cast block-number --rpc-url $L2_URL`
BEHIND=`expr $HEAD - $T1`
MINUTES=`expr $BEHIND / $PROGRESS_PER_MIN`
HOURS=`expr $MINUTES / 60`
echo Hours until sync completed: $HOURS

if [ $HOURS -gt 24 ] ; then
   DAYS=`expr $HOURS / 24`
   echo Days until sync complete: $DAYS
fi
```

{% endcode %}

Then run `./run-estimate.sh` and wait for about 1 minute to see the sync speed and ETA.

```shell
./run-estimate.sh
```

## Official Reference Documentation <a href="#official-resources-and-other-documentation" id="official-resources-and-other-documentation"></a>

Optimism’s guide to building a node: [<img src="https://docs.optimism.io/img/icons/favicon.ico" alt="" data-size="line">Building a Node from Source | Optimism Docs](https://docs.optimism.io/builders/node-operators/tutorials/node-from-source)

Base’s guide to running a node : [<img src="https://docs.base.org/img/favicon.ico" alt="" data-size="line">Running a Base Node | Base](https://docs.base.org/guides/run-a-base-node/)

## Migrating the L2

1. Stop your current L2 node (both `op-node` and `op-geth`)
2. Delete the old state of the goerli network
   1. navigate to datadir
      1. `cd /home/.../op-geth/datadir/`
   2. remove the old state
      1. `sudo rm -rf ./geth`
3. Download the state snapshot for a sepolia L2 following [Setp 3](#step-3-download-the-snapshot)
4. Configure and Start L2 node following [Step 7](#id-6-configure-and-start-op-geth) and [Step 8](#id-6-configure-and-start-op-geth-1)
   1. ignore the jwt parts of it
   2. just extract the snapshot to the right path and run with the correct config&#x20;
5. Refer [Step 9](#id-9.-post-setup) for post setup help

## Upgrading the L2

upgrading your existing L2 to support Ecotone upgrade

1. Stop your current L2 node (both `op-node` and `op-geth`)
2. Upgrade op-geth
   1. <pre data-full-width="false"><code>cd /&#x3C;path>/&#x3C;to>/&#x3C;op-geth>/op-geth
      git pull
      git checkout v1.101308.0
      make geth
      </code></pre>
   2. `./run-geth-optimism.sh` or `./run-geth-base.sh`
3. Upgrade op-node
   1. ```
      cd /<path>/<to>/<optimism>/optimism
      git pull
      git checkout v1.7.0
      make op-node
      ```
   2. `cd op-node`
   3. add the following flag to your op-node run script\
      `--l1.beacon=<L1_BEACON_NODE_URL>`
      1. refer [#id-6-configure-and-start-op-geth-1](#id-6-configure-and-start-op-geth-1 "mention") for how the final script file should look like
   4. `./run-node-optimism.sh` or `./run-node-base.sh`

{% hint style="info" %}
If you don't currently have access to a beacon node, you can setup any of the available software for it, including *Lighthouse*, *Prysm* etc. using their docs. One such guide can be found here to setup a P*rysm* node:\
<https://docs.prylabs.network/docs/install/install-with-script>
{% endhint %}
