> ## Documentation Index
> Fetch the complete documentation index at: https://docs.restaking.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Native delegation for SafeStake with MEV Plus

Running MEV Plus alongside the SafeStake Operator is similar to running
it with a normal Ethereum node. If you haven’t already tried running MEV
Plus [this](https://docs.restaking.cloud/middleware/tutorials/install-native-delegation) tutorial should help you get started in getting set up for
native delegation.

Once the node and the MEV Plus service is running, it boils down to
correctly configuring a SafeStake Operator. This tutorial goes through
the step by step process of installing and running a SafeStake Operator
on Goerli testnet.

<ol>
  <li>
    ### Set firewall rule

    Log in to your host cloud service provider, open the following firewall
    inbound rules:

    | **Type**        | **IpProtocol** | **Port** | **IpRanges** | **Usage**                                                                                      |
    | :-------------- | :------------: | -------: | ------------ | ---------------------------------------------------------------------------------------------- |
    | Inbound/Ingress |    TCP & UDP   |    30303 | 0.0.0.0/0    | Geth/Nethermind/Besu/Erigon p2p                                                                |
    | Inbound/Ingress |    TCP & UDP   |     9000 | 0.0.0.0/0    | Lighthouse p2p                                                                                 |
    | Inbound/Ingress |       TCP      |     5052 | Internal     | Operator - Lighthouse                                                                          |
    | Inbound/Ingress |       TCP      |     8551 | Internal     | Lighthouse - Geth/Nethermind/Besu/Erigon                                                       |
    | Inbound/Ingress |       TCP      |    26000 | 0.0.0.0/0    | hotstuff consensus                                                                             |
    | Inbound/Ingress |       TCP      |    26001 | 0.0.0.0/0    | hotstuff consensus                                                                             |
    | Inbound/Ingress |       TCP      |    26002 | 0.0.0.0/0    | hotstuff consensus                                                                             |
    | Inbound/Ingress |       TCP      |    26003 | 0.0.0.0/0    | When aggregating signatures, operator nodes use this port to request signature from each other |
    | Inbound/Ingress |       UDP      |    26004 | 0.0.0.0/0    | Node discovery                                                                                 |
    | Inbound/Ingress |       TCP      |    26005 | 0.0.0.0/0    | DKG port, which will listen only when DKG is triggered. By default, the port won't listen.     |
  </li>

  <li>
    #### SSH Login to your server
  </li>

  <li>
    #### Install Docker and Docker compose

    * [install docker engine](https://docs.docker.com/engine/install/)

    * [install docker compose](https://docs.docker.com/compose/install/)
  </li>

  <li>
    #### Enable docker service and start it immediately.

    ```javascript theme={null}
    sudo systemctl enable docker
    ```
  </li>

  <li>
    #### Create local volume directory

    ```javascript theme={null}
    sudo mkdir -p /data/geth
    # OR, if you use Nethermind/Besu/Erigon:
    # sudo mkdir -p /data/nethermind
    # sudo mkdir -p /data/besu
    # sudo mkdir -p /data/erigon
    sudo mkdir -p /data/lighthouse
    sudo mkdir -p /data/jwt
    sudo mkdir -p /data/operator
    ```
  </li>

  <li>
    #### Generate your jwt secret to jwt directory

    ```javascript theme={null}
    openssl rand -hex 32 | tr -d "\n" | sudo tee /data/jwt/jwtsecret
    ```
  </li>

  <li>
    #### Clone operator code from Github

    ```javascript theme={null}
    git clone --recurse-submodules
    https://github.com/ParaState/SafeStakeOperator.git dvf
    ```
  </li>

  <li>
    #### Running Geth/Nethermind/Besu/Erigon & Lighthouse Service

    NOTE: This step is to provide a quick way to setup and run the execution
    client and consensus client of goerli testnet. If you already have a
    node running execution client and consensus client, you can skip this
    step.

    ```javascript theme={null}
    cd dvf
    cp .env.example .env
    sudo docker compose -f docker-compose-operator-mev.yml up geth -d# OR,
    if you use Nethermind/Besu/Erigon:# sudo docker compose -f
    docker-compose-operator-mev.yml up nethermind -d# sudo docker compose
    -f docker-compose-operator-mev.yml up besu -d# sudo docker compose -f
    docker-compose-operator-mev.yml up erigon -d
    sudo docker compose -f docker-compose-operator-mev.yml up lighthouse -d
    ```

    NOTE: Remember to open the 5052 firewall port for this host

    Syncing data may take several hours. You can use the command to see the
    latest logs of lighthouse to check if the data is synced:

    ```javascript theme={null}
    sudo docker compose -f docker-compose-operator-mev.yml logs -f --tail 10
    lighthouse
    ```

    Once the data is synced, you will see output like below:

    ```javascript theme={null}
    INFO Synced, slot: 3690668, block: 0x1244…cb92, epoch: 115333,
    finalized_epoch: 115331, finalized_root: 0x0764…2a3d, exec_hash:
    0x929c…1ff6 (verified), peers: 78
    ```

    or you can use this command to check if lighthouse is synced:

    ```javascript theme={null}
    curl -X GET "http://localhost:5052/lighthouse/syncing" -H "accept:
    application/json"
    ```

    if the output shows \{"data":"Synced"}, it means it is already synced.
  </li>

  <li>
    #### Edit local environment variables

    ```javascript theme={null}
    vim.env;
    ```

    Now that we have open the .env file, we will update the values based on
    our own configuration.

    **Leave these variables unchanged now**:

    ```javascript theme={null}
    GETH_NETWORK=goerli
    NETHERMIND_NETWORK=goerli
    BESU_NETWORK=goerli
    ERIGON_NETWORK=goerli
    LIGHTHOUSE_NETWORK=prater
    OPERATOR_NETWORK=prater
    IMAGE_TAG=v1.2-testnet
    REGISTRY_CONTRACT_ADDRESS=f31605c163b54C00371b10af21E8eDa32B969F21
    NETWORK_CONTRACT_ADDRESS=C1b4AA96afA5D3566A86920e69Fc6C274d54F3B4
    API_SERVER=https://api-testnet.safestake.xyz/v1/# different chain has
    different ttd
    TTD=10790000# separated by ',' for multiple relays, such as
    MEV_BOOST_RELAYS=xxx,xxx,xxx
    MEV_BOOST_RELAYS=https://0xafa4c6985aa049fb79dd37010438cfebeb0f2bd42b115b89dd678dab0670c1de38da0c4e9138c9290a398ecd9a0b3110@boost-relay-goerli.flashbots.net#gas
    limit. [default: 30,000,000]
    GAS_LIMIT_INTEGER=30000000
    OPERATOR_ID=<YOUR_OPERATOR_ID>
    ```

    **Update these variables with yours**

    WS\_URL= #YOUR Infura WSS URL

    BEACON\_NODE\_ENDPOINT= # The beacon node endpoint. Depending on
    whether you are running single-node mode or multi-node mode, fill in the
    correct Lighthouse beacon node service url, e.g. [http://127.0.0.1:5052](http://127.0.0.1:5052)
    for a local node

    For BEACON\_NODE\_ENDPOINT, if you follow the previous step to run
    Geth/Nethermind/Besu/Erigon and Lighthouse and you want operator runs on
    the same machine, then you can use a local IP:

    BEACON\_NODE\_ENDPOINT=[http://127.0.0.1:5052](http://127.0.0.1:5052)

    Otherwise, suppose the host where you run the Lighthouse &
    Geth/Nethermind/Besu/Erigon service has an IP 12.102.103.1, then you can
    set:

    BEACON\_NODE\_ENDPOINT=[http://12.102.103.1:5052](http://12.102.103.1:5052)
  </li>

  <li>
    #### Generate a registration public and private key

    ```javascript theme={null}
    sudo docker compose -f docker-compose-operator-mev.yml up dvf_key_tool
    ```

    Output:

    ```javascript theme={null}
    ...

    dvf-dvf_key_tool-1 | INFO: node public key
    AtzozvDHiWUpO+oJph2ikv+EyBN5pdBXsfgZqLi0+Yqd
    dvf-dvf_key_tool-1 exited with code 0
    ```

    Save the public key, which will be used later. Or you can find the
    public key in the "name" field of the file
    /data/operator/v1/prater/node\_key.json
  </li>

  <li>
    #### Go to [SafeStake website](https://testnet.safestake.xyz/):

    * Click "Join As Operator".

    <img height="200" src="https://mintcdn.com/blockswap/T0qQIF803xEE3chz/images/join_safestake.png?fit=max&auto=format&n=T0qQIF803xEE3chz&q=85&s=4ff7ff667d7c22a889e12ad2684bf993" data-path="images/join_safestake.png" />

    * Select a wallet where you
      have enough goerli testnet token to pay minimum fee to sign a transaction.

    <img height="200" src="https://mintcdn.com/blockswap/T0qQIF803xEE3chz/images/metamask.png?fit=max&auto=format&n=T0qQIF803xEE3chz&q=85&s=fc0985a8244c2c877814d3e7a518cba3" data-path="images/metamask.png" />

    * After you connect your wallet, click "Register Operator"

    <img height="200" src="https://mintcdn.com/blockswap/T0qQIF803xEE3chz/images/network_operators.png?fit=max&auto=format&n=T0qQIF803xEE3chz&q=85&s=fb1819867344d7ecad0cba00b9829364" data-path="images/network_operators.png" />

    * Your wallet address is auto filled. You need to enter the "Display Name" for your node and the "Operator Public Key" got from the previous step. Then click "Next".

    <img height="200" src="https://mintcdn.com/blockswap/T0qQIF803xEE3chz/images/register.png?fit=max&auto=format&n=T0qQIF803xEE3chz&q=85&s=8c196a40f6800f1cdfd5745a12bb0728" data-path="images/register.png" />

    * Click "Register Operator"

    <img height="200" src="https://mintcdn.com/blockswap/T0qQIF803xEE3chz/images/network_operators.png?fit=max&auto=format&n=T0qQIF803xEE3chz&q=85&s=fb1819867344d7ecad0cba00b9829364" data-path="images/network_operators.png" />

    * Wallet extension page will pop out. You need to click "Confirm" to sign the transaction.

    <img height="200" src="https://mintcdn.com/blockswap/T0qQIF803xEE3chz/images/confirm.png?fit=max&auto=format&n=T0qQIF803xEE3chz&q=85&s=29c7ee35cd49b2e29b48ab6863834b86" data-path="images/confirm.png" />

    After we register an Operator on the Safestake website, we will be shown
    our OPERATOR ID, which is the unique identifier we need to start with.
    We will need to update the OPERATOR ID to the .env file before running
    the operator service.
  </li>

  <li>
    #### Edit local environment variables for OPERATOR\_ID

    ```javascript theme={null}
    vim.env;
    OPERATOR_ID= #The Operator ID is the ID you receive after registering
    the operator on SafeStake website
    ```
  </li>

  <li>
    #### Start operator service

    ```javascript theme={null}
    sudo docker compose -f docker-compose-operator-mev.yml up
    --force-recreate -d operator
    ```

    *Congratulations, now the Operator program has been installed and
    deployed.*
  </li>
</ol>

### Some final notes about Operator's private/public keys

You can always view your public key in case you forget it with the
command:

```javascript theme={null}
sudo docker compose -f docker-compose-operator-mev.yml logs -f operator
| grep "node public key"
```

output

```javascript theme={null}
dvf-operator-1 | [2022-08-13T16:01:33.814Z INFO
dvf::node::node] node public key
Al0wMNz3JpkYDH7HVp93dZfLMt1GJHypLfhwOWS0NwC/
```

It is a good practice to back up your operator private key file

**Keep it safe and put it in a safe place!**

/data/operator/v1/prater/node\_key.json

Your SafeStake Operator Node is now configured

then you may go to [SafeStake website](https://testnet.safestake.xyz/) to register a validator and then
choose your operator.

## Backup and Migration

If you are using our default settings, all data other than configuration
files is stored in the folder /data. It is possible for
Geth/Nethermind/Besu/Erigon and lighthouse to resync data in a new
machine. For operator, it is important to always backup and copy the
folder /data/operator/ to the new machine before you start operator in
the new machine.

Some description of the folders and files under
/data/operator/v1/prater/:

```javascript theme={null}
── prater
    ├── contract_record.yml # record the current synced block number
    ├── dvf_node_db # hotstuff consensus files
    ├── node_key.json # operator's public and private key
    ├── secrets # secret files for encryption
    ├── validators # data files of the validators that the operator is
serving, inherited from the native folder of lighthouse validator
client, including slashing_protection.sqlite, etc.
```
