Interactive Solo Ethereum staking guide for Ubuntu OS

One-page interactive complete guide to stake one as well as thousands of validators in a single staking node. Simply made, well explained, allowing running multiple chains on a single node. Focused on ethereum.

Disclaimer

This guide is for informational purposes only. The author nor website owner does not guarantee accuracy of the information in this guide and is not responsible for any damages or losses incurred by following the guide.

Prerequisites for this guide

  1. Installed and synced Execution and Consensus client

    Install Execution and Consensus Client

Run a validator

Stakers.space guide works with a concept of validator instances. You are used to have only one validator service from the other staking guides. However, this one service is just a single instance. This guide supports you to set multiple such validator instances on a single machine (if necessary), which has following benefits:

  • You are able to keep validators separated - e.g. based on used deposit / withdrawal / fee recipient wallet address
  • Keep logs in smaller size
  • Remove a limitation of thread perofmance - with more instances you are able to you your CPU and threads in a more efficient way that results in option to run more validators on a single machine.

Under 1 validator instance you can run 1 as well as hundreds of validators. We did numerous tests of efficient number of validators per instances and number of instances on a single machine. We can share this experience under a paid serice.

To configurate an instance of validator service, you need at least one keystore. 1 keystore represents 1 validator. You can generate keystores on an offline PC with Validator Data generator tool, see the guide.

Get Keystores

The tool generates a directory deposit_keys with keystore json files and 1 deposit json file.

Copy keystores to your machine

Before copying, create following directory for keystores on your staking machine

mkdir -p $HOME/keystores

Copy your keystores to $HOME/keystores on your staking machine.

  1. Create a directory for your USB stick (if not created yet)
    sudo mkdir /media/usb
  2. Mount USB stick to /media/usb directory
    sudo mount -t vfat /dev/sda1 /media/usb -o uid=1000
  3. Copy keystores from /media/usb/deposit_keys to $HOME/keystores
    :
    cp -r /media/usb/deposit_keys ~/keystores
  4. Umount USB stick
    sudo umount /media/usb

scp can be only used if you have access to your staking machine over ssh, see securing ssh chapter.

on MacOS / Linux Terminal, from the directory with deposit_keys folder, run the following command:


:
scp -P SSHport -i ~/.ssh/<SSHprivateKEY> -r deposit_keys myserveruser@<IP>:~/keystores

Configurate & Run Validator instance

  1. Do you want to create a new validation instance or extend exisiting instance for more validators?

    • Create a directory for validator instance data

      sudo mkdir -p /var/lib/ethereum/lighthouse/vi1
    • Load keystores to /var/lib/ethereum/lighthouse/vi1

      :
      sudo /usr/local/bin/lighthouse --network mainnet account validator import --reuse-password --directory $HOME/keystores/ddk_i1 --datadir /var/lib/ethereum/lighthouse/vi1
      • Insert keystores encryption password (the one used during keystores generation) on request
      • If there are keystores with different encryption password, repeat the process for each encryption password
    • Create a service user for the validator instance

      sudo useradd --system --no-create-home --shell /bin/false eth-lighthouse-vi1
    • Set ownership of /var/lib/ethereum/lighthouse/vi1 to validators-i1 user

      sudo chown -R eth-lighthouse-vi1:eth-lighthouse-vi1 /var/lib/ethereum/lighthouse/vi1
    • Create configuration service file for eth-lighthouse-vi1 service

      1. Open the configuration file

        sudo nano /etc/systemd/system/eth-lighthouse-vi1.service
      2. Copy the configuration below into the file.

        [Unit]
        Description=Lighthouse Validator Instance (Mainnet)
        Wants=network-online.target
        After=network-online.target
        [Service]
        User=eth-lighthouse-vi1
        Group=eth-lighthouse-vi1
        Type=simple
        Restart=always
        RestartSec=5
        ExecStart=/usr/local/bin/lighthouse vc \
          --network mainnet \
          --datadir /var/lib/ethereum/lighthouse/vi1 \
          --suggested-fee-recipient 0xXXXXXXXXXXXXXXXX \
          --beacon-nodes http://localhost:5052 \
          --graffiti "Nethermind+Lighthouse"
        [Install]
        WantedBy=multi-user.target
      3. Press CTRL + X then Y then ENTER to save and exit the config file.
    • Other configurations

      Nothing to do. You are ok.
      • Extend Staking manager clients.conf

        Insert eth-lighthouse-vi1 into clients.conf file that is used by Staking Manager.
        sudo nano /usr/local/etc/staking/config/clients.conf
    • Stop running validator instance eth-lighthouse-vi1

      sudo systemctl stop eth-lighthouse-vi1
    • Extend /var/lib/ethereum/lighthouse/vi1 for new keystores

      sudo /usr/local/bin/lighthouse --network mainnet account validator import --reuse-password --directory $HOME/keystores/ddk_i1 --datadir /var/lib/ethereum/lighthouse/vi1
      • You will be requested to insert keystores encryption password (the one used during keystores generation)
      • If there are keystores with different encryption password, repeat the process for each encryption password
      • Already existing keystores in the directory will be skipped
  2. Load processed changes to the system

    sudo systemctl daemon-reload
  3. Start the validator instance

    sudo systemctl start eth-lighthouse-vi1
  4. Check the running validator instance

    systemctl status eth-lighthouse-vi1
    journalctl -fu eth-lighthouse-vi1
  5. Activate service to start automatically on OS startup

    $ sudo systemctl enable eth-lighthouse-vi1

Guide to exit validator is available at https://stakers.space/lighthouse#exit-validator.

  1. Do you want to create a new validation instance or extend exisiting instance for more validators?

    • Create a directory for validator instance data

      sudo mkdir -p /var/lib/ethereum/lodestar/vi1
    • Enable accessing /var/lib/ethereum/lodestar/vi1 for server user myserveruser

      sudo chown -R myserveruser:myserveruser /var/lib/ethereum/lodestar/vi1
    • Load keystores to /var/lib/ethereum/lodestar/vi1

      :

      Move to Lodestar client directory

      cd /usr/local/bin/lodestar
      ./lodestar validator import --network mainnet --importKeystores $HOME/keystores/ddk_i1 --dataDir /var/lib/ethereum/lodestar/vi1

      • Insert keystores encryption password (the one used during keystores generation) on request
      • If there are keystores with different encryption password, repeat the process for each encryption password
    • Create a service user for the validator instance

      sudo useradd --system --no-create-home --shell /bin/false eth-lodestar-vi1
    • Set ownership of /var/lib/ethereum/lodestar/vi1 to lodestar-vi1 user

      sudo chown -R eth-lodestar-vi1:eth-lodestar-vi1 /var/lib/ethereum/lodestar/vi1
    • Enable access to NodeJs for user lodestar-vi1

      :
      sudo usermod -aG myserveruser eth-lodestar-vi1
    • Create configuration service file for eth-lodestar-vi1 service

      1. Open the configuration file

        sudo nano /etc/systemd/system/eth-lodestar-vi1.service
      2. Copy the configuration below into the file.

        • :
          This can be get with command $ node version

        [Unit]
        Description=Lodestar Validator Instance (Ethereum Mainnet)
        Wants=network-online.target
        After=network-online.target
        [Service]
        User=eth-lodestar-vi1
        Group=eth-lodestar-vi1
        Type=simple
        Restart=always
        RestartSec=5
        WorkingDirectory=/usr/local/bin/lodestar
        Environment="PATH=/home/myserveruser/.nvm/versions/node/v20.11.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
        ExecStart=/usr/local/bin/lodestar/lodestar validator \
          --network mainnet \
          --dataDir /var/lib/ethereum/lodestar/validators/i1 \
          --suggestedFeeRecipient 0xXXXXXXXXXXXXXXXX \
          # ToDo: Add Beacon API URL
          --force \
          --graffiti "Nethermind+Lodestar"
        [Install]
        WantedBy=multi-user.target
      3. Press CTRL + X then Y then ENTER to save and exit the config file.
    • Adding validator instance to staking services manager

      If you use a staking manager client, add the new instance into it.

    • Stop running validator instance eth-lodestar-vi1

      sudo systemctl stop eth-lodestar-vi1
    • Extend /var/lib/ethereum/lodestar/validators/i1 for new keystores

      ./lodestar validator import --network mainnet --importKeystores $HOME/keystores/ddk_i1 --dataDir /var/lib/ethereum/lodestar/vi1

      • You will be requested to insert keystores encryption password (the one used during keystores generation)
      • If there are keystores with different encryption password, repeat the process for each encryption password
      • Already existing keystores in the directory will be skipped
  2. Load processed changes to the system

    sudo systemctl daemon-reload
  3. Start the validator instance

    sudo systemctl start eth-lodestar-vi1
  4. Check the running validator instance

    systemctl status eth-lodestar-vi1
    journalctl -fu eth-lodestar-vi1
  5. Other configurations

    Activate service to start automatically on OS startup

    $ sudo systemctl enable eth-lodestar-vi1
    • Configurate Lodestar validator Log monitor service

      Log monitor service monitors the service log and process defined action (fixes) in a case of any issue detected.

      1. Check, whether the logmonitor util is installed:
        /usr/local/bin/logmonitor.sh version

        If the util is not installed, install Lodestar validator Log monitor from GitHub.

      2. Check defined Errors list for lodestarvalidator service
        sudo nano /usr/local/etc/lodestarvalidator_tracking_records.txt

        If not available, download it from GitHub. You can also modifiy it, if needed.

      3. Configurate the validator log monitor for service eth-lodestar-vi1, see guide on Github.
    • Activate service to start automatically on OS startup

      Our guide uses a custom util for launching services. It has following benefits:

      • It allows set delay for starting services. It eliminates slashing risk in the following scenario:
        1. A database corruption occures
        2. Lodestar Log monitor detects it, stopping the validator instance and clearing broken database
        3. Very quick power failure happens while the staking node starts immediately automatically
        4. As the database with last attestation is removed now, we need to prevent start of the validator instance to avoid double attestation / block proposal within the same slot.
      • It allows starting services through a shared script

        Starting all services through the Staking Manager util and its command /usr/local/bin/staking.sh start execution prevents a human error when there is forgotten set of sudo systemctl enable ... for any staking-related service.

      There's a Start with delay util to manage this.

      1. Install Start with delay util from GitHub, if not installed yet.
      2. Open Start with delay util
        sudo nano /usr/local/bin/delayed-start.sh
      3. Place new services (validator isntance and validator instance monitor) into the file
        eth-lodestar-vi1
        eth-lodestar-vi1_logmonitor
      4. Verify, that a service `delayed-start.service` exists and is automatically launched on system start. See GitHub for a guide to do that.
    • Extend Staking manager clients.conf

      Insert eth-lodestar-vi1 into clients.conf file that is used by Staking Manager.
      sudo nano /usr/local/etc/staking/config/clients.conf

Guide to exit validator is available at https://stakers.space/lodestar#exit-validator.

  1. Do you want to create a new validation instance or extend exisiting instance for more validators?

    • Create a directory for validator instance data

      sudo mkdir -p /var/lib/ethereum/teku-vi1
    • If exists, remove deposit_data file from keystores folder

      :
      • Display files in the directory
        cd $HOME/keystores/ddk_i1 && ls -lh
      • If there is deposit_data-XXX....json file, remove it
        rm deposit_data-XXX....json
    • Copy keystores dedicated for instance into /var/lib/ethereum/teku-vi1/keystores folder

      sudo mkdir /var/lib/ethereum/teku-vi1/keystores
      sudo cp -a $HOME/keystores/ddk_i1/* /var/lib/ethereum/teku-vi1/keystores && cd /var/lib/ethereum/teku-vi1/keystores
    • Teku requires a .txt file with encryption password for each .json validator file.

      1. Display all keystores in the directory
        ls -lh
      2. .json

        Vreate a new .txt file for the keystore-m_12381_3600_X_0_0-XXXXXXXXXX.json keystore file

        nano keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt

        Insert an encryption password for the validator key (the one used during keystores generation) into that file.

        Press ctrl + x, then y to save and exit

      3. Set readonly permission for that file
        sudo chmod 400 keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt

      Now, you can either repeate the process for all other keystores in the folder, or use an automated solution to duplicate the created password file (with modified name) for all remaining keystores, see Shell Script to generate password files for Teku.

      With automated process, to generate .txt file with a content of /var/lib/ethereum/teku-vi1/keystores/keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt for all remaining keystores in the /var/lib/ethereum/teku-vi1/keystores/ directory, use command

      $HOME/bashscripts/create-teku-pswfiles.sh /var/lib/ethereum/teku-vi1/keystores/keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt

    • Create a service user for the validator instance

      sudo useradd --system --no-create-home --shell /bin/false eth-teku-vi1
    • Set ownership of validator instance data directory to validator-instance user
      sudo chown -R eth-teku-vi1:eth-teku-vi1 /var/lib/ethereum/teku-vi1
    • Create configuration service file for eth-teku-vi1 service

      1. Open the configuration file
        sudo nano /etc/systemd/system/eth-teku-vi1.service
      2. Copy the configuration below into the file.
        [Unit]
        Description=Teku Validator Instance (Ethereum Mainnet)
        Wants=network-online.target
        After=network-online.target
        [Service]
        User=eth-teku-vi1
        Group=eth-teku-vi1
        Type=simple
        Restart=always
        RestartSec=5
        Environment="JAVA_OPTS=-Xmx8g"
        Environment="TEKU_OPTS=-XX:-HeapDumpOnOutOfMemoryError"
        ExecStart=/usr/local/bin/teku/bin/teku validator-client \
          --network mainnet \
          --beacon-node-api-endpoint http://127.0.0.1:5052 \
          #--beacon-node-api-endpoint http://127.0.0.1:5051,http://192.10.10.101:5051,http://192.140.110.44:5051 \
          --data-path /var/lib/ethereum/teku-vi1 \
          --validator-keys /var/lib/ethereum/teku-vi1/keystores:/var/lib/ethereum/teku-vi1/keystores \
          --validators-proposer-default-fee-recipient 0xXXXXXXXXXXXXXXXX \
          --validators-graffiti "Nethermind+Teku"
        [Install]
        WantedBy=multi-user.target
    • Other configurations

      Nothing to do. You are ok.
      • Extend Staking manager clients.conf

        Insert eth-teku-vi1 into clients.conf file that is used by Staking Manager.
        sudo nano /usr/local/etc/staking/config/clients.conf
    • Stop running validator instance eth-teku-vi1

      sudo systemctl stop eth-teku-vi1
    • If exists, remove deposit_data file from keystores folder

      :
      • Display files in the directory
        cd $HOME/keystores/ddk_i1 && ls -lh
      • If there is deposit_data-XXX....json file, remove it
        rm deposit_data-XXX....json
    • Copy keystores dedicated for instance into /var/lib/ethereum/teku-vi1/keystores folder

      sudo mkdir /var/lib/ethereum/teku-vi1/keystores
      sudo cp -a $HOME/keystores/ddk_i1/* /var/lib/ethereum/teku-vi1/keystores/keystores  && cd /var/lib/ethereum/teku-vi1/keystores
    • Teku requires a .txt file with encryption password for each .json validator file.

      1. Display all keystores in the directory
        ls -lh
      2. .json

        Vreate a new .txt file for the keystore-m_12381_3600_X_0_0-XXXXXXXXXX.json keystore file

        nano keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt

        Insert an encryption password for the validator key (the one used during keystores generation) into that file.

        Press ctrl + x, then y to save and exit

      3. Set readonly permission for that file
        sudo chmod 400 keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt

      Now, you can either repeate the process for all other keystores in the folder, or use an automated solution to duplicate the created password file (with modified name) for all remaining keystores, see Shell Script to generate password files for Teku.

      With automated process, to generate .txt file with a content of /var/lib/ethereum/teku-vi1/keystores/keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt for all remaining keystores in the /var/lib/ethereum/teku-vi1/keystores/ directory, use command

      $HOME/bashscripts/create-teku-pswfiles.sh /var/lib/ethereum/teku-vi1/keystores/keystore-m_12381_3600_X_0_0-XXXXXXXXXX.txt

  2. Load changes made in config files to the system

    sudo systemctl daemon-reload
  3. Start the validator instance

    sudo systemctl start eth-teku-vi1
  4. Check the running validator instance

    systemctl status eth-teku-vi1
    journalctl -fu eth-teku-vi1
  5. Activate service to start automatically

    sudo systemctl enable eth-teku-vi1

Guide to exit validator is available at https://stakers.space/teku#exit-validator.