# Home

## <img src="/files/76ATv4bo84zGjGTyHWjq" alt="" data-size="line"> CoinCashew

> **The best how-to guide for all your favorite cryptocurrencies.**
>
> Learn to do anything with crypto, *better*.

## :fire: **HOT TOPICS**

* :pill: Install [**EthPillar**](/coins/overview-eth/ethpillar): one-liner setup tool and node management TUI!
* :blue\_book: [Early Preview: **Hoodi testnet** staking guide](/coins/overview-eth/testnet-hoodi)
* :cut\_of\_meat: Learn to setup your own Ethereum Staking Validator here!
* :moneybag: [Enable MEV-boost for Ethereum Staking](/coins/overview-eth/mev-boost)
* :scream: Don't Panic: [Recover ETH Validator Mnemonic Seed](/coins/overview-eth/guide-or-recover-ethereum-validator-mnemonic-seed)
* :chains: Learn to setup your own [Cardano Stake Pool here!](/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node)

{% hint style="info" %}
:new: **New DISCORD Server: Join** <https://discord.gg/dEpAVWgFNB>
{% endhint %}

## :robot: Blazingly helpful

> "CoinCashew was like the expert crypto mentor I never knew I needed. Saved me so much time and money!" -- TheRealSatoshi

> "One guide to guide them all." --Cambo

> "Crypto explained, ELI5 style" --5 year young

## :dart: Be the contributor, the builder.

Perhaps you wrote your own guide? Scale, share, and amplify your knowledge. [Your pull request contributions are welcome on GitHub!](/contributing)

> Accelerating the adoption of crypto! Yes, you are.

## :star:Stargazers over time

[![Stargazers over time](https://starchart.cc/coincashew/coincashew.svg?variant=adaptive)](https://starchart.cc/coincashew/coincashew)


# About Us

## :wave: Howdy!

Every guide, tip, and review written on CoinCashew was written by someone who wanted to share and help build a better world for everybody. We hope you to see you soon again and keep spreading the knowledge.

## :rocket: Social Links

:alien: **Reddit**: [r/coincashew](https://www.reddit.com/r/coincashew/)

:robot: **Discord**: <https://discord.gg/dEpAVWgFNB> \[New as of May 26, 2024]

:mobile\_phone: **Telegram:** <https://t.me/coincashew>

:bird: **Twitter:** [@coincashew\_](https://twitter.com/coincashew_)

:e-mail: **Email:** <coincashew@protonmail.com>

## :fire: Want to contribute?

Submit a PR on github.com and [get up to speed here](/contributing).

## :sparkles: Credits && Attribution

* [Cryptocurrency Icons](https://github.com/atomiclabs/cryptocurrency-icons) by [atomiclabs](https://github.com/atomiclabs)
* [opnsource.guide](https://github.com/github/opensource.guide) by [github](https://github.com/github)


# Donations

{% hint style="success" %}
Thank you for supporting public goods! Use [cointr.ee to find our donation ](https://cointr.ee/coincashew)addresses. :pray:&#x20;
{% endhint %}

{% embed url="<https://cointr.ee/coincashew>" %}


# Contributing

Thanks for checking out the CoinCashew! We're excited to hear and learn from you. Your experiences will benefit others who read and use these guides.

We've put together the following guidelines to help you figure out where you can best be helpful.

### :notebook\_with\_decorative\_cover: Table of Contents

1. [Types of contributions we're looking for](/contributing#types-of-contributions-were-looking-for)
2. [Ground rules & expectations](/contributing#ground-rules-and-expectations)
3. [How to contribute](/contributing#how-to-contribute)
4. [Style guide](/contributing#style-guide)
5. [Community](/contributing#community)

### :woman\_construction\_worker: Types of contributions we're looking for

There are many ways you can directly contribute to the guides (in descending order of need):

* Fix editorial inconsistencies or inaccuracies
* Add stories, examples, or anecdotes that help illustrate a point
* Revise language to be more approachable and friendly
* Translate guides into other languages

Interested in making a contribution? Read on!

### :triangular\_ruler: Ground rules & expectations

Before we get started, here are a few things we expect from you (and that you should expect from others):

* Be kind and thoughtful in your conversations around this project. We all come from different backgrounds and projects, which means we likely have different perspectives on "how open source is done." Try to listen to others rather than convince them that your way is correct.
* CoinCashew's how-to guides are released with a [Contributor Code of Conduct](/contributing/contributor-covenant-code-of-conduct). By participating in this project, you agree to abide by its terms.
* If you open a pull request, please ensure that your contribution passes all tests. If there are test failures, you will need to address them before we can merge your contribution.
* When adding content, please consider if it is widely valuable. Please don't add references or links to things you or your employer have created as others will do so if they appreciate it.

### :factory: How to contribute

If you'd like to contribute, start by searching through the issues and pull requests to see whether someone else has raised a similar idea or question.

If you don't see your idea listed, and you think it fits into the goals of this guide, do one of the following:

* **If your contribution is minor,** such as a typo fix, open a pull request.
* **If your contribution is major,** such as a new guide, start by opening an issue first. That way, other people can weigh in on the discussion before you do any work.

### :straight\_ruler: Style guide

If you're writing content, see the [style guide](/contributing/style-guide) to help your prose match the rest of the Guides.

### :family\_wwgb: Community

Discussions about the CoinCashew take place on this repository's Issues and Pull Requests sections. Anybody is welcome to join these conversations. There is also a mailing list for regular updates.

Wherever possible, do not take these conversations to private channels, including contacting the maintainers directly. Keeping communication public means everybody can benefit and learn from the conversation.

### :family\_man\_boy\_boy: Attribution

This contributing guide is adapted from the [opensource.guide](https://github.com/github/opensource.guide)


# Contributor Covenant Code of Conduct

### :apple: Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

### :hourglass\_flowing\_sand: Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

### :space\_invader: Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

### :telescope: Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

### :oncoming\_police\_car: Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting <coincashew@protonmail.com>. If the incident involves someone who receives that shared inbox, you can contact an individual maintainer (@bkeepers or @nayafia) at `GitHub username` + `@github.com`. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

### :pray: Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version 1.4, available at [https://contributor-covenant.org/version/1/4](https://contributor-covenant.org/version/1/4/)


# Style Guide

From the GitHub Manual of Style, which this style guide inherits from:

> Words are an important part of how software works. Just as we have a style guide for our code, we have a style guide for our tone and our voice. Even though there may be dozens of people creating a product, it should still sound like we speak in one consistent voice.
>
> In other words, the way we write is just as important as the way we design. Consider these things when writing copy.

### :bulb: Content principles

All written content should follow these principles:

* **Approachability:** Don't assume reader has prior knowledge
* **Brevity:** Keep it simple, link to outside content for deeper dives
* **Curation:** Amplify community best practices vs. any individual's point of view

Content should maintain a light-hearted, but wise (think classy, not overly excited) tone. Open source is fun! Readers should feel inspired, not discouraged, by the tone of your writing, and they should trust you to help them get started.

### :woman\_technologist: Mentions

When referring to people that use GitHub, use @mentions of their username instead of their full name.

* 😄 As @AliceBillington put it...
* 😢 As Alice Billington put it...

When referring to a project on GitHub, link to the repository so others can dive deeper, if they choose.

* 😄 @CharlesDon took a similar approach to Hodl...
* 😢 @CharlesDon took a similar approach to [Hodl](https://github.com)...


# Disclaimer

By visiting this website, CoinCashew\.com, you agree to the following terms.

{% hint style="warning" %}
Education is your best investment.&#x20;

Please do your own due diligence.

Pricing can be volatile.&#x20;

Use of this website does not consistent financial, tax, or legal advice.&#x20;

You agree to take all responsibility or liability for your actions and decisions.&#x20;

Anything presented, stated, allude to should not be considered as an endorsement or professional expert advice.

This site might contain copyrighted material the use of which has not always been specifically authorized by the copyright owner.

All views expressed on this site are the authors and do not represent the opinions of any entity whatsoever which have been, am now, or will be affiliated.

This site assumes no responsibility or liability for any errors or omissions in the content of this site. The information contained in this site is provided on an "as is" basis with no guarantee of completeness, accuracy, usefulness or timeliness and without any warranties or any kind whatsoever, express or implied.

The information contained herein is not intended to be a source of advice or credit analysis with respect to the material presented, and the information and/or documents contained in this website do not constitute investment advice.
{% endhint %}


# Guide: Crypto Wallet Tips 101 - Do's and Don'ts

## :superhero: Getting Crypto Super Powers

Becoming a crypto super hero can be an exhilarating and rewarding journey.

{% hint style="danger" %}
It's critical to grasp a solid understanding of crypto wallets.\
Without such, a wallet can be quickly emptied. :sob:\
There is no help line to call or way to reverse a transaction.\
Remember, only you can defend yourself with knowledge. :right\_facing\_fist:
{% endhint %}

> "**With great power comes great responsibility**"
>
> \- Peter Parker Principle

## :bulb: The Do's and Don'ts of Crypto Wallets

{% hint style="info" %}
Listed in order of **what not to do** alongside with the correct action **to do**.
{% endhint %}

## :compass:1. Using Wallets

| :crossed\_swords: Don't                                           | :white\_check\_mark:Do                                                                                              |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Send a transaction blindly                                        | Double check the cryptocurrency type, amount, and destination address                                               |
| Send a large amount to new address                                | Send a small test transaction firstly                                                                               |
| Type a complicated long address                                   | Avoid typos by using a QR scanner or copy/paste an address                                                          |
| Leave your wallet unattended or unlocked                          | Logout or lock your wallet/device                                                                                   |
| Blindly trust downloaded wallets                                  | Verify the authenticity of a wallet's hash                                                                          |
| Store large amounts of crypto on an exchange or your phone/laptop | Store crypto on a dedicated hardware wallet aka Cold Storage                                                        |
| Use an exchange or 3rd party as a wallet                          | Reduce counterparty risk by using your own wallet                                                                   |
| Carry around too much on mobile wallets                           | Store only what you need for everyday spending on mobile wallets                                                    |
| Use simple to guess/lazy passwords                                | Use a "[password manager](https://learn.shakepay.co/passwords-and-password-managers/)" to generate strong passwords |

{% hint style="danger" %}
Elaborate scams or impersonation attempts are common schemes used by fraudsters to steal your private keys. Don't fall for it!
{% endhint %}

## :key2:2. Managing seed phrase and private keys

| :crossed\_swords: Don't                                                 | :white\_check\_mark:Do                                                                                                                                     |
| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Type/take a photo/save your seed phrase or private keys anywhere online | Always keep your seed phrase or private keys offline                                                                                                       |
| Share your seed phrase with anyone                                      | Understand that anyone, with your seed phrase, can spend your funds                                                                                        |
| Forget your seed phrase/private keys/wallet PINs                        | Backup and write/etch them down on a physical object, not online. Even better, use a [metal seed](https://jlopp.github.io/metal-bitcoin-storage-reviews/). |
| Only have one copy of your seed phrase                                  | Keep multiple copies stored at multiple locations                                                                                                          |
| Only have a seed written on paper.                                      | Plan in case of a fire or flood. Use a [metal seed.](https://jlopp.github.io/metal-bitcoin-storage-reviews/)                                               |

## :closed\_lock\_with\_key:3. Securing your internet, browser & devices

| :crossed\_swords: Don't                                                  | :white\_check\_mark:Do                                    |
| ------------------------------------------------------------------------ | --------------------------------------------------------- |
| Click unknown links that might steal your crypto (phishing)              | Verify the correctness of a website's address             |
| Use a wallet on an old device which may be full of vulnerabilities       | Keep your phone/laptop up-to-date with security patches   |
| Make transactions over public WIFI                                       | Make transactions in a safe environment or over VPN       |
| Use phone number based 2-factor authentication                           | Use Authy or OTP-based 2-factor authentication            |
| Use your personal email for crypto                                       | Use a separate dedicated email for crypto                 |
| Make transactions on insecure websites with only HTTP in the web address | Check for a padlock meaning the website is secure         |
| Mix personal/work devices with lots of crypto                            | Use a device solely for the purpose of transacting crypto |

{% hint style="success" %}
Have any more tips? Feel free to contribute.
{% endhint %}


# Ethereum: ETH

A global, open-source platform for decentralized applications. On Ethereum, you can write code that controls digital value, runs exactly as programmed, and is accessible anywhere in the world.

## <img src="/files/-M6JC7QUlZuQXmvhR8b8" alt="" data-size="original"> General Data

| Site        | Title                                               |
| ----------- | --------------------------------------------------- |
| Website     | <https://www.ethereum.org/>                         |
| Source Code | <https://github.com/ethereum>                       |
| Whitepaper  | <https://github.com/ethereum/wiki/wiki/White-Paper> |

## :person\_raising\_hand: Social Media and Community

| Community       | Link                                    |
| --------------- | --------------------------------------- |
| :bird: Twitter  | <https://twitter.com/ethereum>          |
| Reddit          | <https://reddit.com/r/ethereum>         |
| Official Forums | <https://forum.ethereum.org/>           |
| Gitter          | <https://gitter.im/orgs/ethereum/rooms> |

## :arrows\_clockwise: Block Explorers

| Site                                              |
| ------------------------------------------------- |
| [Etherscan.io](https://etherscan.io/)             |
| [Blockchair.com](https://blockchair.com/ethereum) |
| [Ethplorer.io](https://ethplorer.io/)             |
| [Etherchain.org](https://etherchain.org/)         |
| [beaconcha.in](https://beaconcha.in/)             |

## :bar\_chart: Charts and Pricing

| Site          | Link                                               |
| ------------- | -------------------------------------------------- |
| CoinPaprika   | <https://coinpaprika.com/coin/eth-ethereum/>       |
| CoinMarketCap | <https://coinmarketcap.com/currencies/ethereum/>   |
| CoinGecko     | <https://www.coingecko.com/en/coins/ethereum>      |
| LiveCoinWatch | <https://www.livecoinwatch.com/price/Ethereum-ETH> |


# EthPillar: one-liner setup tool and node management TUI

Empowered, inspired, home staker. Free. Open source. Public goods for Ethereum. ARM64 and AMD64 support. Lido CSM Compatible. Jumpstart your ETH solo-staking / Lido CSM journey.

{% hint style="danger" %}
DOCUMENTATION HAS MOVED TO > <https://docs.coincashew.com/ethpillar>

Below is for historical reference purposes only.
{% endhint %}

<figure><img src="/files/vB2fdLA9WhUnSHknKEJm" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}

#### Do you like this software? Star the project and become a [⭐ Stargazer](https://github.com/coincashew/ethpillar/stargazers)

{% endhint %}

## :arrow\_forward: Quickstart: Ubuntu One-liner Install

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

{% hint style="success" %}
**Important Safety Best Practice:** Avoid downloading untrusted scripts. Unverified code may pose security risks. Double-check the script or ask someone trusted for verification. Only install after confirming its authenticity.
{% endhint %}

## :new: What is EthPillar?

:smile: **Friendly Node Installer**: Helps you deploy a systemd installation with minority clients Nimbus-Nethermind or Teku-Besu stack in just minutes. MEVboost included.

:floppy\_disk: **Ease of use**: No more remembering CLI commands required. Access common node operations via a simple text user interface (TUI).

:owl: **Fast Updates**: Quickly find and download the latest consensus/execution release. Less downtime!

:tada:**Compatibility**: Behind the scenes, node commands and file structure are identical to V2 staking setups.&#x20;

{% hint style="warning" %}
Already a running a Validator? EthPillar is compatible with [a Coincashew V2 Staking Setup.](https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet)&#x20;
{% endhint %}

## :fire: Features

:chains: **Hoodi and Ephemery Testnet Support**: Quickest and easiest way run a node now, risk free. Learn and practice here before moving to mainnet.

:droplet: **Lido CSM Integration**: Deploys in minutes and start staking via [Lido's CSM with as little as 2.4 ETH](https://csm.testnet.fi/?ref=ethpillar).

:tools: **Plugins and Tools**: Node-checker, eth-validator-cli, Dora the lightweight block explorer, contributoor, Ethdo, client-stats, csm-sentinel and eth-duties Integration helps stakers with every day common tasks.

:bacon: **Grafana and Ethereum-Metrics-Exporter Integration:** Monitoring and dashboards has never been easier.

:mag\_right:  **Built-in Troubleshooting:** Find common issues preventing your node from it's peak performance. Discover EthPillar's built-in Node Checker which checks for common system issues.

:tada: **Multiple deployment configurations:** Deploy a Solo Staking Node, Full Node Only, Lido CSM Staking Node, Validator Client Only or Failover Staking Node.

## :sunglasses: Preview

<figure><img src="/files/F8aiTwRxmsGnB0RET0oj" alt=""><figcaption><p>Main Menu</p></figcaption></figure>

<div><figure><img src="/files/PeZO1BK1XiEEruol1NNs" alt=""><figcaption><p>Execution Client</p></figcaption></figure> <figure><img src="/files/WbxUqrL6KPX1lRNms1Fy" alt=""><figcaption><p>Consensus Client</p></figcaption></figure> <figure><img src="/files/vOS3BPDHb5yhEaQ7Guny" alt=""><figcaption><p>Validator</p></figcaption></figure></div>

<figure><img src="/files/i8wg4UbA4igENTNb22sC" alt=""><figcaption><p>Tools</p></figcaption></figure>

<div><figure><img src="/files/DNKvobUWxOuSU8kAGTfu" alt=""><figcaption><p>Plugins</p></figcaption></figure> <figure><img src="/files/Qx3tUM3vskTAg6hohu5z" alt=""><figcaption><p>Mevboost</p></figcaption></figure> <figure><img src="/files/PqCWrnADQxzKT4OIfNWC" alt=""><figcaption><p>System Administration</p></figcaption></figure></div>

## :tada: Speedrun Demo by Stakesaurus

{% embed url="<https://www.youtube.com/watch?v=aZLPACj2oPI>" %}

## :whale: Prerequisites

* Study [Ethstaker's Staking for Beginners](https://www.reddit.com/r/ethstaker/wiki/staking_for_beginners/)
* [Review how staking works and the hardware requirements](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/prerequisites)
* A Linux [Ubuntu](https://ubuntu.com/download) installation.&#x20;
  * Tested with [Ubuntu 24.04 LTS](https://ubuntu.com/download) Server
  * Also appears compatible with [armbian](https://www.armbian.com/download/), [Linux Mint](https://www.linuxmint.com/), [Debian 12](https://www.debian.org/distrib/netinst)
  * Support for **AMD64 and ARM64** architecture
  * Recommend at least 16GB RAM for **ARM64** sbc

## :triangular\_ruler: Option 1: Automated One-Liner Install

Open a terminal window from anywhere by typing `Ctrl+Alt+T`.&#x20;

To install, paste the following:

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

## :handshake: Option 2: Manual Install

**Install updates and packages:**

```bash
sudo apt-get update && sudo apt-get install git curl ccze bc tmux jq nano btop whiptail ufw
```

**Clone the ethpillar repo and install:**

```bash
mkdir -p ~/git/ethpillar
git clone https://github.com/coincashew/ethpillar.git ~/git/ethpillar
sudo ln -s ~/git/ethpillar/ethpillar.sh /usr/local/bin/ethpillar
```

#### Run ethpillar:

```bash
ethpillar
```

## :tada:Next Steps

{% hint style="success" %}
Congrats on installing a EthPillar, making nodes and home staking easier!
{% endhint %}

<details>

<summary>All types of node operators: Solo staking, Full node, CSM Staking Node</summary>

**Step 1: Configure your network, port forwarding and firewall.**&#x20;

* With EthPillar, configuration can be changed at:
  * **Tools > UFW Firewall > Enable firewall with default settings**
  * Port forwarding is [manually configured](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-2-configuring-node#configure-port-forwarding), depending on your router.
  * Confirm port forwarding is working with **Tools** > **Port Checker**
* Alternatively configure manually per the manual guide. [Click here for detailed network configuration.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-2-configuring-node#network-configuration)

**Step 2: Configure your BIOS to auto power on after power loss**

Actual steps vary depending on your computer's BIOS. General idea here: <https://www.wintips.org/setup-computer-to-auto-power-on-after-power-outage/>

**Step 3: Enable Monitoring and Alerts (Optional)**

Found under:

* **Tools** > **Monitoring**

**Step 4: Benchmark your node (Optional)**

Ensure your node has sufficient CPU/disk/network performance.

* **Tools** > **Yet-Another-Bench-Script**

</details>

<details>

<summary>Lido CSM Staking Node Operators</summary>

**Step 1: Generate Validator Keys:**

* Generate new CSM validator keys for the Lido withdrawal vault
* `Ethpillar > Validator Client > Generate / Import Validator Keys`

**Step 2: Upload JSON Deposit Data:**

* Upload the newly generated deposit data file for your CSM keystores to the Lido CSM Widget. [CSM Holesky](https://csm.testnet.fi/?ref=ethpillar) or [CSM Mainnet](https://csm.lido.fi/?ref=ethpillar)
* Provide the required bond amount in ETH/stETH/wstETH.

**Step 3: Monitor Validator Key Deposit:**

* Wait for your CSM validator keys to be deposited by Lido.&#x20;
* Ensure your node remains online during the process.

</details>

<details>

<summary>Additional steps for Solo Stakers</summary>

**Step 1: Setup Validator Keys**

* Familarize yourself with the main guide's section on [setting up your validator keys.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-5-installing-validator/setting-up-validator-keys)
* When ready to generate your keys, go to **EthPillar > Validator Client > Generate / Import Validator Keys**

**Step 2: Upload deposit\_data.json to Launchpad**

* To begin staking on Ethereum as a validator, you need to submit to the Launchpad your  deposit\_data.json file, which includes crucial withdrawal address details, and pay the required deposit of 32ETH per validator.

**Step 3: Congrats!**&#x20;

* Now you're waiting in the Entry Queue [https://www.validatorqueue.com](https://www.validatorqueue.com/)
* Check out the [next steps from the main guide](https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-5-installing-validator/next-steps) for further knowledge. Especially the FAQ's "Wen staking rewards?"

</details>

## :question: FAQ

<details>

<summary>Change Networks: How to switch between testnet and mainnet with EthPillar ?</summary>

To switch to mainnet, there are two recommended methods.

* **Cleanest and most problem-free option**: Reformat Ubuntu OS and re-install EthPillar.&#x20;
* **Use EthPillar:** Navigate to **System Administration > Change Network**

</details>

<details>

<summary>Exit Validator: How do I exit a validator?</summary>

If you already have VEMs created, skip to step 2.

Step 1: Navigate to EthPillar > Validator > Generate Voluntary Exit Message

Step 2: Broadcast Voluntary Exit Message

</details>

<details>

<summary>Add Validators: I already have validators running. I want to add one more validator. How do I do that?</summary>

Navigate to,

**EthPillar > Validator Client > Generate / Import Validator Keys**

From there you will pick 1 of 2 options.

* Import validator keys from offline key generation or backup
* Add new or regenerate existing validator keys from Secret Recovery Phrase

</details>

<details>

<summary>Node Types: What is a failover staking node?</summary>

**Purpose**: To provide high availability, you would run TWO (or more) failover staking nodes on separate machines. Point your validator client to your two failover staking nodes.

**What**: A failover staking node is made up of an execution client, consensus client and mevboost.

**How to**: To configure for nimbus validator client, edit your validator client configuration. <https://nimbus.guide/validator-client-options.html#multiple-beacon-nodes>

Exposing the consensus client RPC port will also be required. You will need to adjust your firewall to allow traffic from your validator client's IP address as well.

**Benefit**: Running multiple failover staking nodes (or beacon nodes as nimbus refers to it) would allow you to perform maintenance or have an outage on 1 failover staking node.

</details>

<details>

<summary>Withdrawal Address: Can I have different withdraw addresses per validator or only 1 per setup?</summary>

Different withdrawal addresses per validator are possible if you run the ./deposit tool separately for each validator.

</details>

<details>

<summary>Generating Keystores: Can I generate 10 validator keystores and activate them one by one at the launchpad?</summary>

You can but it would require manual editing as you'll need to change the deposit\_data json.

</details>

<details>

<summary>Migrate or Upgrade Staking Setup: How to switch to EthPillar from a V1 Staking setup or other staking tool</summary>

To migrate from a different staking setup, find your most applicable situation:

**Cleanest and most problem-free option**:&#x20;

* 1\) Reformat Ubuntu Operating System
* 2\) Install EthPillar
* 3\) Import validator keys

**Existing V1 Staking Setup:** OGs and genesis stakers :saluting\_face:

* 1\) [Uninstall V1 Staking Setup](/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance/uninstalling-v1-staking-node)
* 2\) Install EthPillar
* 3\) Import validator keys

**Other staking automation tools or cloud hosted setups:**&#x20;

* 1\) Uninstall / cancel / existing tool or service provider
* 2\) Install EthPillar
* 3\) Import validator keys

:white\_check\_mark: **To avoid slashing penalties**, ensure your validator keys are deleted from existing staking setups.

</details>

## :telephone: Get in touch

Have questions? Chat with other home stakers on [Discord](https://discord.gg/dEpAVWgFNB) or open PRs/issues on [Github](https://github.com/coincashew/ethpillar).&#x20;

Open source source code available here: <https://github.com/coincashew/EthPillar>

## :heart: Donations

If you'd like to support this public goods project, find us on the next Gitcoin Grants.

Our donation address is [0xCF83d0c22dd54475cC0C52721B0ef07d9756E8C0](https://etherscan.io/address/0xCF83d0c22dd54475cC0C52721B0ef07d9756E8C0) or coincashew\.eth

## :ballot\_box\_with\_check: How to Update

{% tabs %}
{% tab title="TUI Update" %}
Upon opening EthPillar,

* Navigate to **System Administration > Update EthPillar** and then quit and relaunch.
  {% endtab %}

{% tab title="Manual Update" %}
From a terminal, pull the latest updates from git.

```bash
cd ~/git/ethpillar
git pull
```

{% endtab %}
{% endtabs %}

## :star2:Contribute

We appreciate any help! To join in:

* Star the project on [GitHub](https://github.com/coincashew/EthPillar).
* Share the project on X or reddit. Talk about your experiences with solo staking.
* Provide feedback on [Github](https://github.com/coincashew/EthPillar/issues).
* [Submit PRs](https://github.com/coincashew/EthPillar/pulls) to improve the code.

## :tada: Credits

Shout out to [accidental-green](https://github.com/accidental-green/validator-install) for their pioneering work in Python validator tools, which has unintentionally ignited the inspiration and direction for this project. We are building upon their innovative foundations by forking their validator-install code. A heartfelt thanks to accidental-green for their game-changing contributions to the open-source Ethereum ecosystem!


# Guide | How to setup a validator for Ethereum staking on mainnet

Using the gold standard of ETH staking, become a solo home staker. Help decentralize Ethereum, a proof-of-stake blockchain. Anyone with 32 ETH can join.

{% hint style="danger" %}
DOCUMENTATION HAS MOVED TO > <https://docs.coincashew.com/guides/mainnet>

Below is for historical reference purposes only.
{% endhint %}

## :rocket:Option 1: Quickstart with EthPillar - Recommended for most users

### :arrow\_forward:  Ubuntu One-liner Install:

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

😄 **Friendly Node Installer**: Helps you deploy a systemd installation with minority clients Nimbus-Nethermind or Teku-Besu stack in just minutes. MEVboost included. Lido CSM supported.

:floppy\_disk: **Ease of use**: No more remembering CLI commands required. Access common node operations via a simple text user interface (TUI). When EthPillar is deployed, operating your node becomes a breeze.

:owl: **Fast Updates**: Quickly find and download the latest consensus/execution release. Less downtime!

#### :exclamation:To learn more about EthPillar, [visit the quickstart page.](/coins/overview-eth/ethpillar)

<figure><img src="/files/HCFPqea9Z5MktcDDPTvQ" alt=""><figcaption><p>EthPillar's TUI - Navigate the menu to control your node</p></figcaption></figure>

### :chains:Option 2: Manual Installation

* This guide aims to reduce the reliance on scripts in this section to make the learning process more straightforward and understandable.
* This approach provides a detailed overview of the steps involved, ensuring stakers have a clear understanding of the process.
* Great for advanced users comfortable with the CLI terminal who want full control and require customization of EL/CL combinations and their configurations.
* Deploys a systemd installation with any EL/CL combination you choose.
* After installation, use [EthPillar](/coins/overview-eth/ethpillar) to simplify maintenance of your node.

#### To install manually, continue with this guide.

#### :shield: Built by home-stakers for home-stakers. :pray:


# Overview - Manual Installation

## :new: Announcements

{% hint style="success" %}
As of July 6 2024, this **Version 2 Guide** written for **🦉Dencun**🦉 **MAINNET Ethereum** :grin:
{% endhint %}

{% hint style="info" %}
:sparkles: **Always test and practice on testnet first. See** [Holesky testnet ](/coins/overview-eth/testnet-holesky-validator)guide.
{% endhint %}

{% hint style="warning" %}
:eyes: Started staking pre-Merge? Use the **Version 1 MAINNET Guide.** [Available here.](/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet)
{% endhint %}

## :wrench: About This Guide

For the advanced user who wants customization and is comfortable with CLI commands, this guide will walk you through the details of setting up a validator. For most users, the quickest and automated way to setup a staking node is with [EthPillar](/coins/overview-eth/ethpillar).

The following parts make up this guide:

* [**Part I - Installation**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation) describes in 5 steps how to setup your staking node.
* [**Part II - Maintenance**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance) explains ongoing tasks you'll require to keep your staking node in great shape and up-to-date.
* [**Part III - Tips**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips) contains additional procedures to simplify managing your staking node.

## :thumbsup: Your Github Contributions Welcome

This guide is fully open source and fully powered by home-stakers like you.

Pull requests or issues can be submitted on [github](https://github.com/coincashew/coincashew).

{% embed url="<https://github.com/coincashew/coincashew>" %}

#### :arrow\_up: [View Changelog](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/changelog): See the latest changes to the guide.


# PART I - INSTALLATION

Installation is a 5 step process. From start to finish, time to complete these steps can take up to a few hours. Fully syncing your the node can take a day or two. If you're not sure, become comfortable by practicing on [testnet](/coins/overview-eth/testnet-holesky-validator).

* Step 1: Prerequisites
* Step 2: Configuring Node
* Step 3: Installing execution client
* Step 4: Installing consensus client
* Step 5: Installing Validator


# Step 1: Prerequisites

## :rocket: How Staking on Ethereum Works

1. Acquire some hardware (laptop, desktop, server) or rent a VPS (cloud server): You need to run a node to stake.
2. Sync an execution layer client
3. Sync a consensus layer client
4. Generate your validator keys and import them into your validator client
5. Monitor and maintain your node

A Ethereum node consists of the Execution Layer + Consensus Layer.

A Ethereum Staking node is the previous plus a Validator client.

<figure><img src="/files/s1oKZXCcrZioRrPAMkps" alt=""><figcaption><p>Client Stack</p></figcaption></figure>

<figure><img src="/files/gY9TruKmwgL2Jn9yFe1U" alt=""><figcaption><p>Big picture: Execution / Consensus / Validator</p></figcaption></figure>

## :wave: Introduction

This guide was written for aspiring Ethereum stakers who have basic familiarity with command line tools and it was tested against Ubuntu LTS client. You’ll want a dedicated cloud VPS or local desktop/server/laptop running a clean install of Ubuntu preferably.

### Terminology

Your Ethereum staking node may be

* **Local:** on a laptop / PC / NUC that you can physically connect keyboard/mouse/monitor.
* **Remote:** in the cloud on a VPS

If your staking node is **remote**, then you will want to setup SSH, secure shell.

If using a VPS or **remote** node, install and start the SSH client for your operating system:

**Windows**: [PuTTY](https://www.puttygen.com/download-putty)

**MacOS and Linux**: from the Terminal, use the native command:

```
ssh <YourUserName>@<YourServersIP>
```

Here's a [guide from Makeuseof](https://www.makeuseof.com/tag/beginners-guide-setting-ssh-linux-testing-setup/) to connect by SSH to your **remote node.**

## :hammer\_pick: How to Run Commands

* Commands are to be run in a terminal window or ssh terminal.
* Commands preceded by `sudo` will prompt for your password at first, and periodically afterwards.

## :woman\_technologist: Skills for operating an staking node

As a validator for Ethereum, you will typically have the following abilities:

* operational knowledge of how to set up, run and maintain a Ethereum consensus client, execution client and validator continuously
* a long term commitment to maintain your validator 24/7/365
* basic operating system skills

## :man\_technologist: Experience required to be a successful ETH Staker

* have studied [Ethstaker's Staking for Beginners](https://www.reddit.com/r/ethstaker/wiki/staking_for_beginners/)
* have perused the vast tomes of the [EthStaker Knowledge Base](https://docs.ethstaker.cc/ethstaker-knowledge-base/)

## :man\_lifting\_weights: Recommended Node Setup Requirements

* **Operating system:** Ubuntu LTS Server or Desktop
* **Processor:** 4 CPU Cores or more
* **Memory:** 32GB RAM
* **Storage:** Mainnet: 4TB NVME (not QLC). Testnet: 300GB
* **Internet:** Stable broadband internet connections with speeds at least 20 Mbps without data limit.
* **Data Plan**: At least 2 TB per month. Ideally, no data cap or unlimited data plan.
* **Power:** Reliable electrical power with a [Uninterruptible Power Supply (UPS)](https://www.lifewire.com/best-uninterrupted-power-supplies-4142625).
* **ETH balance:** 2.4ETH for [Lido CSM](https://csm.lido.fi/?ref=ethpillar) or at least 32 ETH for solo staking with 1 validator
* **Wallet**: [Rabby](https://rabby.io/) Wallet installed

{% hint style="info" %}
:desktop: **Hardware Builds**: For examples of actual staking hardware builds, check out [RocketPool's hardware guide](https://github.com/rocket-pool/docs.rocketpool.net/blob/main/docs/guides/node/local/hardware.md#example-setups) and [Ethstaker's Hardware Examples](https://docs.ethstaker.cc/ethstaker-knowledge-base/hardware/hardware-examples).
{% endhint %}

{% hint style="info" %}
:cd: **Storage Suggestion**: Check out the following to find your ideal NVME or SSD drive.

* [**Yorick's Storage Advice**](https://gist.github.com/yorickdowne/f3a3e79a573bf35767cd002cc977b038): Refer to Yorick's Great and less great SSDs for Ethereum nodes
* [**Top SSD List**](https://docs.google.com/spreadsheets/d/1B27_j9NDPU3cNlj2HKcrfpJKHkOf-Oi1DbuuQva2gT4/edit)**:** Suitable drives are identified as Mid-Range or better.
  {% endhint %}

<figure><img src="/files/X2z463D8wsbAfaAYxeJg" alt=""><figcaption><p>Ethereum Staking Node</p></figcaption></figure>

{% hint style="success" %}
:sparkles: **Pro Validator Tip**: Highly recommend you begin with a brand new instance of an OS, VM, and/or machine. Avoid headaches by NOT reusing testnet keys, wallets, or databases for your validator.
{% endhint %}

## :desktop: Local Node vs Remote Node

**Decision**: Do I run my Ethereum staking node locally at home or rent a VPS cloud server remotely? Here's a list of criteria to help you decide.

|       Criteria       | Local Node                                                                                                                                         | Remote Node                                                                                                                                                                 |
| :------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|     Ongoing Costs    | Plus - No fees, besides internet bill and electricity.                                                                                             | Minus - Monthly or Annual reoccurring rental fees.                                                                                                                          |
| Hardware Maintenance | Minus - Do it yourself if hardware issues.                                                                                                         | Plus - Included, covered by hosting provider.                                                                                                                               |
|       Internet       | Minus - Can slow down home internet and use up data plan (if not unlimited) Budget for at least 2TB per month data plan.                           | Plus - Often plans are generous and more than sufficient for an ETH node.                                                                                                   |
|      Reliability     | Minus - Do it yourself with UPS, redundant internet connections, computer issues                                                                   | Plus - Hosted in a data center with multiple power/internet backups.                                                                                                        |
|   Barrier to Entry   | <p>Plus - Can re-use or re-purpose existing hardware<br><br>Minus - Initial cost to purchase new computer equipment</p>                            | Plus - Renting a VPS might require a lower initial investment as you can pay monthly.                                                                                       |
|   Decentralization   | Plus - Home staking is the **gold standard** for Ethereum decentralization, nothing bets it!                                                       | Minus - VPS cloud hosts like [Netcup](https://www.netcup.eu/bestellen/produkt.php?produkt=3026) or AmazonWebServices are by nature more centralized.                        |
|     Customization    | Plus - More fine control over hardware configuration                                                                                               | Minus - May be limited choices and hardware can be shared. For example, a common issue is insufficient disk storage I/O speeds (IOPS).                                      |
|       Security       | Plus - As secure as your home and personal [OPSEC](https://en.wikipedia.org/wiki/Operations_security)                                              | <p>Plus - Enterprise-grade, professional data centers.</p><p>Minus - Not your hardware, not your node. It's possible the hosting provide can view your node's contents.</p> |
|        Freedom       | <p>Plus - Do whatever you want. Plan your own upgrades.<br><br>Minus - With great freedom and power, you are solely responsible for your node.</p> | <p>Plus - Professionally managed.</p><p><br>Minus - At the mercy of the host's actions, data center outages are possible.</p>                                               |

## :tools: Setup Ubuntu

With your local or remote node, now you need to install an Operating System. This guide is designed for Ubuntu LTS.

* To install **Ubuntu Server or Desktop**, refer to this [guide](https://docs.ethstaker.cc/ethstaker-knowledge-base/tutorials/installing-linux).

{% hint style="info" %}
**Recommendation**: A headless (no monitor) install of **Ubuntu Server** on a **dedicated** NUC/laptop/desktop/VPS is best for ease of reliability and security. :fire: Do not use this system for email/browsing web/gaming/socials. :fire:
{% endhint %}

{% hint style="warning" %}
**Tip**: When installing Ubuntu Server, ensure you are selecting “**Use an entire disk**” on the **Guided storage configuration** screen. Next screen will be the **Storage configuration** screen, ensure your settings are using all available disk storage. A [common issue](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/using-all-available-lvm-disk-space) is that Ubuntu server defaults to using only 200GB.
{% endhint %}

## :performing\_arts: Setup Rabby

When the time comes to make your validator's 32ETH deposit(s), you'll need a wallet to transfer funds to the beacon chain deposit contract.

* To install Rabby, visit their [official site.](https://rabby.io/)

## :jigsaw: High Level Validator Node Overview

{% hint style="info" %}
At the end of this guide, you will build a staking validator node that hosts three main components in two layers: consensus layer consists of a consensus client, also known as a validator client with a beacon chain client. The execution layer consists of a execution client, formerly a eth1 node.

**Validator client** - Responsible for producing new blocks and attestations in the beacon chain and shard chains.

**Consensus client** - Responsible for managing the state of the beacon chain, validator shuffling, and more.

**Execution client** - Supplies incoming validator deposits from the eth mainnet chain to the beacon chain client.
{% endhint %}

![How Ethereum nodes fits together featuring Leslie the Rhino, the mascot named after American computer scientist Leslie Lamport](/files/-MPCDQuE1PFqzrv0AzuT)


# Step 2: Configuring Node

## :hammer\_pick: Node Configuration

### Logging to the node

**Using Ubuntu Server**: Begin by connecting with your SSH client.

```bash
ssh username@staking.node.ip.address
```

**Using Ubuntu Desktop**: You're likely in-front of your **local** node. Simply open a terminal window from anywhere by typing Ctrl+Alt+T.

### Updating the node

Ensure all the latest packages, tools and patches are installed first, then reboot.

```bash
sudo apt-get update -y && sudo apt dist-upgrade -y
sudo apt-get install git ufw curl ccze jq -y
sudo apt-get autoremove
sudo apt-get autoclean
sudo reboot
```

## :key: Security Configuration

### Create a non-root user with sudo privileges

<details>

<summary>Creating a user called ethereum</summary>

Create a new user called `ethereum`

```bash
sudo useradd -m -s /bin/bash ethereum
```

Set the password for ethereum user

```bash
sudo passwd ethereum
```

Add ethereum to the sudo group

```bash
sudo usermod -aG sudo ethereum
```

Log out and log back in as this new user.

**Using Ubuntu Server**: Use the following commands.

```bash
exit
ssh ethereum@staking.node.ip.address
```

**Using Ubuntu Desktop**: Log out can be found in the top right corner under the Power Icon. Click the `ethereum` user account and enter password.

</details>

{% hint style="warning" %}
:fire:**Important reminder**: Ensure you are logged in and execute all steps in this guide as this non-root user, `ethereum`.
{% endhint %}

### Hardening SSH Access

{% hint style="info" %}
**Local node**? You can skip this section on Hardening SSH Access.
{% endhint %}

<details>

<summary>Creating a new SSH Key</summary>

Create a new SSH key pair on **your client machine (i.e. local laptop)**. Run this on **your client machine,** not remote node. Update the comment with your email or a comment.

```
ssh-keygen -t ed25519 -C "name@email.com"
```

You'll see this next:

```
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/<myUserName>/.ssh/id_ed25519):
```

Here you're asked to type a file name in which to save the SSH private key. If you press enter, you can use the default file name `id_ed25519`

Next, you're prompted to enter a passphrase.

```
Enter passphrase (empty for no passphrase):
```

:information\_source: A **passphrase** adds an extra layer of protection to your SSH private key. Everytime you connect via SSH to your remote node, enter this passphrase to unlock your SSH private key.

:fire: Passphrase is highly recommended! Do not leave this empty for no passphrase.

:bulb:Do not forget or lose your passphrase. Save this to a password manager.

**Location**: Your SSH key pair is stored in your home directory under `~/.ssh`

**File name:** If your default keyname is`id_ed25519`, then

* your **private SSH key** is `id_ed25519`
* your **public SSH key** is `id_ed25519.pub`

:fire: **IMPORTANT:** Make multiple backup copies of your **private SSH key file** to external storage, such as a USB backup key, for recovery purposes. Also backup your **passphrase**!

Verify the contents of your private SSH key file before moving on.

```
cat ~/.ssh/id_ed25519
```

It should look similar to this example.

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBAblzWLb7/0o62FZf9YjLPCV4qFhbqiSH3TBvZXBiYNgAAAJCWunkulrp5
LgAAAAtzc2gtZWQyNTUxOQAAACBAblzWLb7/0o62FZf9YjLPCV4qFhbqiSH3TBvZXBiYNg
AAAEAxT+yCmifGWgbFnkauf0HyOAJANhYY5EElEX8fI+M4B0BuXNYtvv/SjrYVl/1iMs8J
XioWFuqJIfdMG9lcGJg2AAAACWV0aDJAZXRoMgECAwQ=
-----END OPENSSH PRIVATE KEY-----
```

</details>

#### Transferring the SSH Public Key to Remote node

<details>

<summary>Option 1: Transferring with ssh-copy-id</summary>

Works with Linux or MacOS. Use option 2 for Windows.

```bash
ssh-copy-id -i ~/.ssh/id_ed25519 ethereum@staking.node.ip.address
```

</details>

<details>

<summary>Option 2: Copying the key manually</summary>

First, begin by obtaining your SSH Public key.

For Linux/Mac,

```
cat ~/.ssh/id_ed25519.pub
```

For Windows,

Open a command prompt (Windows Key + R, then `cmd`, finally press enter).

```
type %USERPROFILE%\.ssh\id_ed25519.pub
```

The output will look similar to the following:

```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAoc78lv+XDh2znunKXUF/9zBNJrM4Nh67yut9RN14SX name@email.com
```

Copy into your clipboard this output, also known as your public SSH key.

On your **remote node**, run the following:

```
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys
```

First, a directory called **.ssh** is created, then `Nano` is a text editor for editing a special file called **authorized\_keys**

With nano opening the authorized\_keys file, right-click your mouse to paste your public SSH key into this file.

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

Verify your public SSH key was properly pasted into the file.

```
cat ~/.ssh/authorized_keys
```

</details>

#### Disabling Password Authentication

<details>

<summary>Disabling root login and password based login</summary>

:information\_source: With SSH key authentication enabled, there's still the possibility to connect to your remote node with login and password, a much less secure and brute force-able attack vector.

Login via ssh with your new ethereum user

```
ssh ethereum@staking.node.ip.address
```

Edit the ssh configuration file

```
sudo nano /etc/ssh/sshd_config
```

Locate **PubkeyAuthentication** and update to yes. Delete the # in front.

```
PubkeyAuthentication yes
```

Locate **PasswordAuthentication** and update to no. Delete the # in front.

```
PasswordAuthentication no
```

Locate **PermitRootLogin** and update to prohibit-password. Delete the # in front.

```
PermitRootLogin prohibit-password
```

Locate **PermitEmptyPasswords** and update to no. Delete the # in front.

```
PermitEmptyPassword no
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

Validate the syntax of your new SSH configuration.

```
sudo sshd -t
```

If no errors with the syntax validation, restart the SSH process.

```
sudo systemctl restart sshd
```

Verify the login still works.

```
ssh ethereum@staking.node.ip.address
```

**Optional**: Make logging in easier by updating your local ssh config.

To simplify the ssh command needed to log in to your server, consider updating on your local client machine the `$HOME/myUserName/.ssh/config` file:

```bash
Host ethereum-server
  User ethereum
  HostName <staking.node.ip.address>
  Port 22
```

This will allow you to log in with `ssh ethereum-server` rather than needing to pass through all ssh parameters explicitly.

</details>

### Synchronizing time with Chrony

chrony is an implementation of the Network Time Protocol and helps to keep your computer's time synchronized with NTP.

{% hint style="info" %}
Because the consensus client relies on accurate times to perform attestations and produce blocks, your node's time must be accurate to real NTP time within 0.5 seconds.
{% endhint %}

To install chrony:

```bash
sudo apt-get install chrony -y
```

To see the source of synchronization data.

```
chronyc sources
```

To view the current status of chrony.

```
chronyc tracking
```

### Setting Timezone

To pick your timezone run the following command:

```bash
sudo dpkg-reconfigure tzdata
```

Find your region using the simple text-based GUI.

In the event that you are using national system like India's `IST` select:

```
Asia/Kolkata
```

This will be appropriate for all locales in the country (`IST`, `GMT+0530`).

### Creating the jwtsecret file

A jwtsecret file contains a hexadecimal string that is passed to both Execution Layer client and Consensus Layer clients, and is used to ensure authenticated communications between both clients.

```bash
#store the jwtsecret file at /secrets
sudo mkdir -p /secrets

#create the jwtsecret file
openssl rand -hex 32 | tr -d "\n" | sudo tee /secrets/jwtsecret

#enable read access
sudo chmod 644 /secrets/jwtsecret
```

## :link: Network Configuration

The standard UFW - Uncomplicated firewall can be used to control network access to your node and protect against unwelcome intruders.

### Configure UFW Defaults

By default, deny all incoming traffic and allow outgoing traffic.

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Configure SSH Port 22

If your node is remote in the cloud, or at home but on a different headless server, you will need to enable SSH port 22 in order to connect.

```bash
# Allow ssh access for remote node
sudo ufw allow 22/tcp comment 'Allow SSH port'
```

If your node is local at home and you have **keyboard access** to it, it's good practice to deny SSH port 22.

```bash
# Deny ssh access for local node
sudo ufw deny 22/tcp comment 'Deny SSH port'
```

### Allow Execution Client Port 30303

Peering on port 30303, execution clients use this port for communication with other network peers.

```bash
sudo ufw allow 30303 comment 'Allow execution client port'
```

### Allow Consensus Client port

Consensus clients generally use port 9000 for communication with other network peers. Using tcp port 13000 and udp port 12000, Prysm uses a slightly different configuration.

```bash
# Lighthouse, Lodestar, Nimbus, Teku
sudo ufw allow 9000 comment 'Allow consensus client port'

# Lighthouse Quic Port https://lighthouse-blog.sigmaprime.io/Quic.html
sudo ufw allow 9001/udp comment 'Allow lighthouse client quic port'

# Prysm
sudo ufw allow 13000/tcp comment 'Allow consensus client port'
sudo ufw allow 12000/udp comment 'Allow consensus client port'
```

### Enable firewall

Finally, enable the firewall and review the configuration.

```bash
sudo ufw enable
sudo ufw status numbered 
```

Example of ufw status for a remote staking node configured for Prysm consensus client.

```csharp
     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 9000                       ALLOW IN    Anywhere
[ 3] 30303                      ALLOW IN    Anywhere
[ 4] 22/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 5] 9000 (v6)                  ALLOW IN    Anywhere (v6)
[ 6] 30303 (v6)                 ALLOW IN    Anywhere (v6)
```

### Configure Port Forwarding

**Port Forwarding Tip for Local Stakers at Home:** You'll need to forward ports to your validator.

For optimal connectivity, ensure Port Forwarding is setup for your router. Learn to port forward with guides found at [https://portforward.com/how-to-port-forward](https://portforward.com/how-to-port-forward/)

Verify port forwarding is working with the following.

**Option 1:** From the terminal on staking machine. Choose accordingly to your clients.

```bash
# Lighthouse, Lodestar, Nimbus, Teku
curl https://eth2-client-port-checker.vercel.app/api/checker?ports=30303,9000

# Prysm
curl https://eth2-client-port-checker.vercel.app/api/checker?ports=30303,12000,13000
```

**Result:** Open ports will be shown if reachable from public.

\
**Option 2:** Using the browser

* <https://www.yougetsignal.com/tools/open-ports/>
* or <https://canyouseeme.org>

As an example, for Lighthouse, you would verify ports 9000 and 30303 are reachable.

### Optional: Whitelisting Connections

Whitelisting, which means permitting connections from a specific IP, can be setup via the following command.

```bash
sudo ufw allow from <your client machine>
# Example
# sudo ufw allow from 192.168.50.22
```

### :chains: **Install Fail2ban**

{% hint style="info" %}
Fail2ban is an intrusion-prevention system that monitors log files and searches for particular patterns that correspond to a failed login attempt. If a certain number of failed logins are detected from a specific IP address (within a specified amount of time), fail2ban blocks access from that IP address.
{% endhint %}

To install fail2ban:

```bash
sudo apt-get install fail2ban -y
```

Edit a config file that monitors SSH logins.

```bash
sudo nano /etc/fail2ban/jail.local
```

Add the following lines to the bottom of the file.

```bash
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

Restart fail2ban for settings to take effect.

```bash
sudo systemctl restart fail2ban
```


# Step 3: Installing execution client

Your choice of either [**Besu**](https://besu.hyperledger.org)**,** [**Nethermind**](https://www.nethermind.io)**, Geth,** [**Reth**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-3-installing-execution-client/reth) **or** [**Erigon**](https://github.com/ledgerwatch/erigon)**.**

{% hint style="warning" %}
Only one execution client is required per node.
{% endhint %}

## **Execution Client Diversity**

* To strengthen Ethereum's resilience against potential attacks or consensus bugs, it's best practice to run a minority client in order to increase client diversity.
* Find the latest distribution of execution clients here: [https://clientdiversity.org](https://clientdiversity.org/)

<figure><img src="/files/0OnebPfVnFfirmtThJAt" alt=""><figcaption><p>EL Diversity as of Dec 2024</p></figcaption></figure>

## Overview of Execution Clients

{% hint style="info" %}
:shield: **Recommendation** :shield:: **Nethermind** or **Besu**
{% endhint %}

### Nethermind

* Nethermind: Open-source Ethereum client written in .NET Core.
* Fast sync speed: Boasts the quickest Execution client syncing performance and is designed so you can start following the chain and attesting while it downloads history in the background.
* Flexible configuration: Rich set of options tailored for node operators.
* Online pruning: Allows database pruning while still online, no need to turn off client.
* Resource-intensive pruning process: May result in noticeable performance degradation for low-power nodes during the process.

### Besu

* Hyperledger Besu: Open-source Ethereum client under Apache 2.0 license, written in Java.
* Distinctive features: Uses Bonsai Tries for state storage for enhanced performance and benefits.
* Maintenance-free: Does not require pruning, making it effectively maintenance-free.

### Geth

* Geth (Go Ethereum): One of the original Ethereum protocol implementations, written in Go and fully open source under GNU LGPL v3 license.
* Stable and reliable: Oldest and most widely-used Execution Client with a strong reputation.
* Multithreaded: Utilizes the entire CPU for enhanced performance.
* Adjustable RAM usage: Configurable down to 4 GB minimum for Mainnet, accommodating various system specifications.

### Erigon

* Erigon: High-performance Ethereum implementation focused on efficiency, faster synchronization, and optimized experience written in Go.
* Born as a Geth fork, completely rewritten for enhanced speed and storage savings.
* Faster archive node synchronization: Achieves full node synchronization in under three days with less than 2TB of storage.
* Supports several popular EVM-compatible blockchains and testnets.
* Efficient state storage: Utilizes a key-value database for improved performance.
* Separate JSON RPC daemon: Enables read-only calls without requiring the same system as the main Erigon binary, even from a database snapshot.

### Reth

* Reth: Execution layer (EL) Ethereum client, written in Rust, is compatible with all consensus layer (CL) implementations.
* Developed by Paradigm, licensed under Apache and MIT licenses.
* Capabilities: Sending/receiving transactions, querying logs and traces, and accessing/interacting with smart contracts.
* Prioritizing security, efficiency, and ease-of-use for consumer hardware.

## Comparison of Execution Clients

<table><thead><tr><th>Client</th><th width="111">RAM Use</th><th>Minimum Database Size</th><th>Database Growth</th><th>Time to sync</th></tr></thead><tbody><tr><td><strong>Nethermind</strong></td><td>8 GB</td><td>0.95 TB</td><td>18 GB/week</td><td>Fastest, 2hrs+</td></tr><tr><td><strong>Besu</strong></td><td>12 GB</td><td>1.2 TB</td><td>10 GB/week</td><td>Medium, 16hrs+</td></tr><tr><td><strong>Geth</strong></td><td>8 GB</td><td>1.2 TB</td><td>8 GB/week</td><td>Fast, 8hrs+</td></tr><tr><td><strong>Erigon 3</strong></td><td>8 GB</td><td>0.92 GB</td><td>8 GB/week</td><td>Medium, 16hrs+</td></tr><tr><td><strong>Reth</strong></td><td>10 GB</td><td>1.2 TB</td><td>4GB/week</td><td>Medium, 16hrs+</td></tr></tbody></table>

#### Notes:

* Time to sync to a state capable beginning attestations depends on the IOPs of your storage drive.
* Initial sync is always resource intensive. Synced operation is relatively resource use light.
* Nethermind, Besu, Geth have the capability to prune the database.


# Nethermind

## Overview

{% hint style="info" %}
**Nethermind** is a flagship Ethereum client all about performance and flexibility. Built on **.NET** core, a widespread, enterprise-friendly platform, Nethermind makes integration with existing infrastructures simple, without losing sight of stability, reliability, data integrity, and security.
{% endhint %}

#### Official Links

| Subject       | Link                                                                                |
| ------------- | ----------------------------------------------------------------------------------- |
| Releases      | <https://github.com/NethermindEth/nethermind/releases>                              |
| Documentation | [https://docs.nethermind.io](https://docs.nethermind.io/)                           |
| Website       | [https://nethermind.io/nethermind-client](https://nethermind.io/nethermind-client/) |

### 1. Initial configuration

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/nethermind
sudo chown -R execution:execution /var/lib/nethermind
```

Install dependencies.

```bash
sudo apt update
sudo apt install ccze curl libsnappy-dev libc6-dev jq libc6 unzip -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.&#x20;
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-zip and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/NethermindEth/nethermind/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-x64)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O nethermind.zip $BINARIES_URL
unzip -o nethermind.zip -d $HOME/nethermind
rm nethermind.zip
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/nethermind /usr/local/bin/nethermind
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install .NET SDK build dependencies.

```bash
# Get latest .net sdk
curl -L https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
chmod +x ./dotnet-install.sh
./dotnet-install.sh --channel 9.0 --runtime aspnetcore
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
# Clone the repo
git clone https://github.com/NethermindEth/nethermind.git
cd nethermind
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
dotnet publish src/Nethermind/Nethermind.Runner -c release -o nethermind
```

Verify Nethermind was properly built by checking the version.

```shell
./nethermind/nethermind --version
```

Sample output of a compatible version.

```
Version: 1.25.2+78c7bf5f
Commit: 78c7bf5f2c0819f23e248ee6d108c17cd053ffd3
Build Date: 2024-01-23 06:34:53Z
OS: Linux x64
Runtime: .NET 8.0.1
```

Install the binaries.

<pre class="language-shell"><code class="lang-shell"><strong>sudo mv $HOME/git/nethermind/nethermind /usr/local/bin
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Nethermind Execution Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=always
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
WorkingDirectory=/var/lib/nethermind
Environment="DOTNET_BUNDLE_EXTRACT_BASE_DIR=/var/lib/nethermind"
ExecStart=/usr/local/bin/nethermind/nethermind \
  --config mainnet \
  --datadir="/var/lib/nethermind" \
  --Network.DiscoveryPort 30303 \
  --Network.P2PPort 30303 \
  --Network.MaxActivePeers 50 \
  --JsonRpc.Port 8545 \
  --JsonRpc.EnginePort 8551 \
  --Metrics.Enabled true \
  --Metrics.ExposePort 6060 \
  --JsonRpc.JwtSecretFile /secrets/jwtsecret \
  --Pruning.Mode=Hybrid \
  --Pruning.FullPruningTrigger=VolumeFreeSpace \
  --Pruning.FullPruningThresholdMb=375810 \
  --Pruning.FullPruningMemoryBudgetMb=16384 \
  --Pruning.FullPruningMaxDegreeOfParallelism=2 \
  --Pruning.FullPruningCompletionBehavior=AlwaysShutdown
  
[Install]
WantedBy=multi-user.target
```

{% hint style="info" %}
Nethermind will prune the database when disk space is low (below 300GB)
{% endhint %}

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu execution | ccze
```

A properly functioning **Nethermind** execution client will indicate "Received new block". For example,

```
Nethermind.Runner[2]: 29 Sep 03:00:00 | Received new block:  8372 (0x425ab9...854f4)
Nethermind.Runner[2]: 29 Sep 03:00:00 | Processed                8372     |      0.17 ms  |  slot     13,001 ms |
Nethermind.Runner[2]: 29 Sep 03:00:00 | - Block               0.00 MGas   |      0    txs |  calls      0 (  0) | sload       0 | sstore      0 | create   0
Nethermind.Runner[2]: 29 Sep 03:00:00 | - Block throughput    0.00 MGas/s |      0.00 t/s |       7217.16 Blk/s | recv        0 | proc        0
Nethermind.Runner[2]: 29 Sep 03:00:00 | Received ForkChoice: Head: 8372 (0x425ab9...854f4), Safe: 8350 (0xfd781...c2e19f), Finalized: 8332 (0x9ccf...88684c)
Nethermind.Runner[2]: 29 Sep 03:00:00 | Synced chain Head to 8372 (0x425ab9...2881a5)
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/nethermind/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Besu

## Overview

{% hint style="info" %}
**Hyperledger Besu** is an open-source Ethereum client designed for demanding enterprise applications requiring secure, high-performance transaction processing in a private network. It's developed under the Apache 2.0 license and written in **Java**.
{% endhint %}

#### Official Links

| Subject       | Link                                                                    |
| ------------- | ----------------------------------------------------------------------- |
| Releases      | <https://github.com/hyperledger/besu/releases>                          |
| Documentation | [https://besu.hyperledger.org](https://besu.hyperledger.org/en/stable/) |
| Website       | <https://www.hyperledger.org/use/besu>                                  |

### 1. Initial configuration

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/besu
sudo chown -R execution:execution /var/lib/besu
```

Install dependencies.

```bash
sudo apt install -y openjdk-21-jdk libjemalloc-dev jq
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/hyperledger/besu/releases/latest"
TAG=$(curl -s $RELEASE_URL | jq -r .tag_name)
BINARIES_URL="https://github.com/hyperledger/besu/releases/download/$TAG/besu-$TAG.tar.gz"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O besu.tar.gz $BINARIES_URL
tar -xzvf besu.tar.gz -C $HOME
rm besu.tar.gz
sudo mv $HOME/besu-${TAG} besu
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/besu /usr/local/bin/besu
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
# Clone the repo
git clone https://github.com/hyperledger/besu.git
cd besu
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
./gradlew installDist
```

Verify Besu was properly built by checking the version.

```shell
./build/install/besu/bin/besu --version
```

Sample output of a compatible version.

```
besu/v23.4.0/linux-x86_64/openjdk-java-17
```

Install the binaries.

<pre class="language-shell"><code class="lang-shell"><strong>sudo cp -a $HOME/git/besu/build/install/besu /usr/local/bin/besu
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Besu Execution Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment="JAVA_OPTS=-Xmx5g"
ExecStart=/usr/local/bin/besu/bin/besu \
  --network=mainnet \
  --p2p-port=30303 \
  --rpc-http-port=8545 \
  --engine-rpc-port=8551 \
  --max-peers=25 \
  --metrics-enabled=true \
  --metrics-port=6060 \
  --rpc-http-enabled=true \
  --sync-mode=SNAP \
  --data-storage-format=BONSAI \
  --data-path="/var/lib/besu" \
  --engine-jwt-secret=/secrets/jwtsecret
  
[Install]
WantedBy=multi-user.target
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu execution | ccze
```

A properly functioning **Besu** execution client will indicate "Fork-Choice-Updates". For example,

```
2022-03-19 04:09:36.315+00:00 | vert.x-worker-thread-0 | INFO  | EngineForkchoiceUpdated | Consensus fork-choice-update: head: 0xcd2a_8b32..., finalized: 0xfa22_1142...
2022-03-19 04:09:48.328+00:00 | vert.x-worker-thread-0 | INFO  | EngineForkchoiceUpdated | Consensus fork-choice-update: head: 0xff1a_f12a..., finalized: 0xfa22_1142...
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/besu/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Geth

## Overview

{% hint style="danger" %}
:octagonal\_sign:**Strongly discouraged** :octagonal\_sign:**: GETH can be** [**hazardous to your all YOUR STAKE.**](https://twitter.com/EthDreamer/status/1749355402473410714)

Select a minority client.&#x20;

**Recommendation:** Besu or Nethermind.
{% endhint %}

{% hint style="info" %}
**Geth** - Go Ethereum is one of the three original implementations (along with C++ and Python) of the Ethereum protocol. It is written in **Go**, fully open source and licensed under the GNU LGPL v3.
{% endhint %}

#### Official Links

| Subject       | Link                                                    |
| ------------- | ------------------------------------------------------- |
| Releases      | <https://github.com/ethereum/go-ethereum/releases>      |
| Documentation | <https://geth.ethereum.org/docs>                        |
| Website       | [https://geth.ethereum.org](https://geth.ethereum.org/) |

### 1. Create service account and data directory

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/geth
sudo chown -R execution:execution /var/lib/geth
```

### **2. Install binaries**

* Downloading binaries is often faster and more convenient.&#x20;
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

<pre class="language-bash"><code class="lang-bash">RELEASE_URL="https://geth.ethereum.org/downloads"
<strong>FILE="https://gethstore.blob.core.windows.net/builds/geth-linux-amd64[a-zA-Z0-9./?=_%:-]*.tar.gz"
</strong>BINARIES_URL="$(curl -s $RELEASE_URL | grep -Eo $FILE | head -1)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O geth.tar.gz $BINARIES_URL
tar -xzvf geth.tar.gz -C $HOME
rm geth.tar.gz
sudo mv $HOME/geth-* geth
</code></pre>

Install the binaries.

```bash
sudo mv $HOME/geth/geth /usr/local/bin
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install Go dependencies. Latest version [available here](https://go.dev/dl/).

```bash
wget -O go.tar.gz <LATEST VERSION URL FROM ABOVE>
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go.tar.gz
echo export PATH=$PATH:/usr/local/go/bin >> $HOME/.bashrc
source $HOME/.bashrc
```

Verify Go is properly installed by checking the version and cleanup files.

```bash
go version
rm go.tar.gz
```

Install build dependencies.

```bash
sudo apt-get update
sudo apt install build-essential git
```

Build the binary.

```bash
mkdir -p ~/git
cd ~/git
git clone -b master https://github.com/ethereum/go-ethereum.git
cd go-ethereum
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
make geth
```

Install the binary.

<pre class="language-bash"><code class="lang-bash"><strong>sudo cp $HOME/git/go-ethereum/build/bin/geth /usr/local/bin
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

<pre class="language-bash"><code class="lang-bash">[Unit]
Description=Geth Execution Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/geth \
    --mainnet \
    --port 30303 \
    --http.port 8545 \
    --authrpc.port 8551 \
    --maxpeers 50 \
    --metrics \
    --http \
    --datadir=/var/lib/geth \
    --pprof \
    --state.scheme=path \
    --authrpc.jwtsecret=/secrets/jwtsecret
   
<strong>[Install]
</strong>WantedBy=multi-user.target
</code></pre>

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

<pre class="language-bash"><code class="lang-bash"><strong>sudo journalctl -fu execution | ccze
</strong></code></pre>

A properly functioning **Geth** execution client will indicate "Imported new potential chain segment". For example,

```
geth[4531]: INFO [02-04|01:20:48.280] Chain head was updated    number=16000 hash=2317ae..c41107
geth[4531]: INFO [02-04|01:20:49.648] Imported new potential chain segment       number=16000 hash=ab173f..33a21b
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/geth/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Erigon

{% hint style="info" %}
**Erigon** - Successor to OpenEthereum, Erigon is an implementation of Ethereum (aka "Ethereum client"), on the efficiency frontier, written in Go.
{% endhint %}

## Overview

#### Official Links

| Subject       | Link                                                  |
| ------------- | ----------------------------------------------------- |
| Releases      | <https://github.com/erigontech/erigon/releases>       |
| Documentation | [https://docs.erigon.tech](https://docs.erigon.tech/) |
| Website       | [https://erigon.tech](https://erigon.tech/)           |

### 1. Initial configuration

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/erigon
sudo chown -R execution:execution /var/lib/erigon
```

Install dependencies.

```bash
sudo apt install curl libsnappy-dev libc6-dev jq libc6 unzip -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/erigontech/erigon/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux_amd64.tar.gz)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O erigon.tar.gz $BINARIES_URL
tar -xzvf erigon.tar.gz -C $HOME
mv erigon_* erigon
```

Install the binaries and cleanup.

```bash
sudo mv $HOME/erigon/erigon /usr/local/bin
rm -rf erigon erigon.tar.gz
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install Go dependencies. Latest version [available here](https://go.dev/dl/).

```bash
wget -O go.tar.gz <LATEST VERSION URL FROM ABOVE>
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go.tar.gz
echo export PATH=$PATH:/usr/local/go/bin >> $HOME/.bashrc
source $HOME/.bashrc
```

Verify Go is properly installed by checking the version and cleanup files.

```bash
go version
rm go.tar.gz
```

Install build dependencies.

```bash
sudo apt-get update
sudo apt install build-essential git
```

Build the binary.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/erigontech/erigon.git
cd erigon
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
make erigon
```

Install the binary.

<pre class="language-bash"><code class="lang-bash"><strong>sudo cp $HOME/git/erigon/build/bin/erigon /usr/local/bin
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Erigon Execution Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/erigon \
   --datadir /var/lib/erigon \
   --chain mainnet \
   --port 30303 \
   --torrent.port 42069 \
   --maxpeers 50 \
   --private.api.addr 127.0.0.1:9099 \
   --authrpc.port 8551 \
   --http.api web3,eth,net,engine \
   --metrics \
   --pprof \
   --prune.mode minimal \
   --authrpc.jwtsecret=/secrets/jwtsecret \
   --externalcl=true

[Install]
WantedBy=multi-user.target
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu execution | ccze
```

A properly functioning **Erigon** execution client will indicate "Handling new payload". For example,

```
erigon[3]: [INFO] [09-29|03:36:24.689] [NewPayload] Handling new payload        height=19999 hash=0xea060...2846a907ceb4
erigon[3]: [INFO] [09-29|03:36:25.278] [updateForkchoice] Fork choice update: flushing in-memory state (built by previous newPayload)
erigon[3]: [INFO] [09-29|03:36:25.280] RPC Daemon notified of new headers       from=19998 to=19999 hash=0xeeed..710b597 header sending=13.32µs log sending=290ns
erigon[3]: [INFO] [09-29|03:36:25.280] head updated                             hash=0xea06098ad5e...5e5f43 number=20000
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/erigon/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Reth

## Overview

{% hint style="info" %}
**Reth** - short for Rust Ethereum, is an Ethereum full node implementation that is focused on being user-friendly, highly modular, as well as being fast and efficient.
{% endhint %}

### Official Links

| Subject       | Link                                  |
| ------------- | ------------------------------------- |
| Releases      | <https://github.com/paradigmxyz/reth> |
| Documentation | <https://paradigmxyz.github.io/reth/> |
| Website       | <https://www.paradigm.xyz/oss/reth>   |

### 1. Create service account and data directory

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/reth
sudo chown -R execution:execution /var/lib/reth
```

Install dependencies.

```bash
sudo apt-get update
sudo apt install -y ccze jq curl
```

### **2. Install binaries**

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

```bash
RELEASE_URL="https://api.github.com/repos/paradigmxyz/reth/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r '.assets[] | select(.name | startswith ("reth")) | .browser_download_url' | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O reth.tar.gz $BINARIES_URL
tar -xzvf reth.tar.gz -C $HOME
rm reth.tar.gz
```

Install the binaries and display the version.

```bash
sudo mv $HOME/reth /usr/local/bin
reth --version
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

**Install rust dependency**

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

When prompted, enter '1' to proceed with the default install.

Update your environment variables.

```bash
echo export PATH="$HOME/.cargo/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
```

Install rust dependencies.

```bash
sudo apt-get update
sudo apt install -y git libclang-dev pkg-config build-essential
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/paradigmxyz/reth.git
cd reth
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build the release
cargo build --release --features jemalloc
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
cargo build --release --features jemalloc
```

Verify Reth was built properly by checking the version number.

```bash
~/git/reth/target/release/reth --version
```

Install the binary.

```bash
sudo cp ~/git/reth/target/release/reth /usr/local/bin
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

<pre class="language-bash"><code class="lang-bash">[Unit]
Description=Reth Execution Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment=RUST_LOG=info
ExecStart=/usr/local/bin/reth node \
    --full \
    --chain mainnet \
    --datadir=/var/lib/reth \
    --metrics 127.0.0.1:6060 \
    --port 30303 \
    --discovery.port 30303 \
    --enable-discv5-discovery \
    --discovery.v5.port 30304 \
    --http \
    --http.port 8545 \
    --http.api="rpc,eth,web3,net,debug" \
    --log.file.directory=/var/lib/reth/logs \ 
    --max-outbound-peers 25 \
    --max-inbound-peers 25 \
    --authrpc.jwtsecret=/secrets/jwtsecret
   
<strong>[Install]
</strong>WantedBy=multi-user.target
</code></pre>

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

<pre class="language-bash"><code class="lang-bash"><strong>sudo journalctl -fu execution | ccze
</strong></code></pre>

A properly functioning **Reth** execution client will indicate "Block added to canonical chain". For example,

```
INFO reth::node::events: Forkchoice updated head_block_hash=2317ae..c41107 safe_block_hash=ab173f..33a21b finalized_block_hash=ab173f..33a21b status=Valid
INFO reth::node::events: Block added to canonical chain number=16000 hash=2317ae..c41107
INFO reth::node::events: Canonical chain committed number=16000 hash=2317ae..c41107 elapsed=12.508272ms
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/reth/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Step 4: Installing consensus client

Your choice of either Lighthouse, Lodestar, Teku, Nimbus, or Prysm.

{% hint style="warning" %}
Only one consensus client is required per node.
{% endhint %}

## **Consensus Client Diversity**

* To strengthen Ethereum's resilience against potential attacks or consensus bugs, it's best practice to run a minority client in order to increase client diversity.
* Find the latest distribution of consensus clients here: [https://clientdiversity.org](https://clientdiversity.org/)

<figure><img src="/files/t6VDQN5IEZ6XFhsab8xq" alt=""><figcaption><p>CL Diversity as of Dec 2024</p></figcaption></figure>

## Overview of Consensus Clients

{% hint style="info" %}
:shield: **Recommendation** :shield:: Teku, Nimbus, or Lodestar
{% endhint %}

### Lighthouse

* Lighthouse: Open-source Ethereum 2.0 project by Sigma Prime, following Ethereum Foundation Research specification.
* Innovative features: Implements advanced blockchain technologies like proof-of-stake consensus, parallel transaction execution, and sharding (state separation).
* Independently managed: Not officially affiliated with the Ethereum Foundation, adheres to their guidance as long beneficial for Ethereum protocol and community.
* Implemented in Rust: Prioritizes security and efficiency through language choice.

### Lodestar

* Lodestar: Open-source Ethereum consensus client by ChainSafe Systems, known for production-ready beacon chain and validator client.
* Flagship product: Ideal for researchers and developers due to rapid prototyping and browser usage capabilities.
* Typescript implementation: Distinctive feature, aligns with familiarity of millions of developers worldwide.
* Light client expertise: Pioneering research, standardization, and implementation of Ethereum light clients.
* Collaborative approach: Works with other implementers, researchers, and developers to promote trustless data usage from the blockchain.

### Teku

* Teku (formerly Artemis): Enterprise-focused Ethereum consensus client developed by PegaSys, an ConsenSys division.
* Apache 2.0 licensed: Open-source with flexible usage permissions.
* Written in Java: Mature and widely used programming language for increased institutional appeal and security requirements.
* Developed by PegaSys: An arm of ConsenSys dedicated to creating enterprise-ready Ethereum clients and tools.

### Nimbus

* Nimbus: Open-source Ethereum client compatible with both Ethereum 2.0 and Ethereum 1.0.
* Lightweight resource usage: Designed for optimal performance on embedded systems and resource-restricted devices.
* Versatile application: Also suitable for running alongside other workloads, beneficial for stakers looking to minimize server costs.
* Implemented in Nim: Written using the Nim programming language.
* Maintained by Status.im team.

### Prysm

* Prysm: Full-featured Ethereum 2.0 implementation in Go programming language.
* Developed by Prysmatic Labs.
* Adheres to official Ethereum 2.0 specification, evolving collectively through research and development efforts from various Ethereum ecosystem teams including the Ethereum Foundation.

## Comparison of Consensus Clients

<table><thead><tr><th>Client</th><th width="108">CPU Use</th><th width="111">RAM Use</th><th>Database Size</th><th>Time to sync head</th></tr></thead><tbody><tr><td><strong>Lighthouse</strong></td><td>Medium</td><td>6 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Lodestar</strong></td><td>Medium</td><td>8 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Teku</strong></td><td>Medium</td><td>10 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Nimbus</strong></td><td>Low</td><td>3 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Prysm</strong></td><td>Medium</td><td>6 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr></tbody></table>

#### Notes:

* As databases expand beyond 300GB in size over time, checkpoint sync allows nodes to efficiently resynchronize and significantly reduce their database sizes while minimizing downtime.


# Lighthouse

## Overview

{% hint style="info" %}
[Lighthouse](https://github.com/sigp/lighthouse) is an Eth client with a heavy focus on speed and security. The team behind it, [Sigma Prime](https://sigmaprime.io), is an information security and software engineering firm who have funded Lighthouse along with the Ethereum Foundation, Consensys, and private individuals. Lighthouse is built in Rust and offered under an Apache 2.0 License.
{% endhint %}

#### Official Links

| Subject       | Links                                                                           |
| ------------- | ------------------------------------------------------------------------------- |
| Releases      | <https://github.com/sigp/lighthouse/releases>                                   |
| Documentation | [https://lighthouse-book.sigmaprime.io](https://lighthouse-book.sigmaprime.io/) |
| Website       | [https://lighthouse.sigmaprime.io](https://lighthouse.sigmaprime.io/)           |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/lighthouse
sudo chown -R consensus:consensus /var/lib/lighthouse
```

Install dependencies.

```bash
sudo apt install curl jq ccze -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.&#x20;
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/sigp/lighthouse/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lighthouse.tar.gz $BINARIES_URL
# Untar
tar -xzvf lighthouse.tar.gz -C $HOME
# Cleanup
rm lighthouse.tar.gz
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/lighthouse /usr/local/bin/lighthouse
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

**Install rust dependency**

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

When prompted, enter '1' to proceed with the default install.

Update your environment variables.

```bash
echo export PATH="$HOME/.cargo/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
```

Install rust dependencies.

```bash
sudo apt-get update
sudo apt install -y git gcc g++ make cmake pkg-config libssl-dev libclang-dev clang protobuf-compiler
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone -b stable https://github.com/sigp/lighthouse.git
cd lighthouse
make
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
make
```

Verify lighthouse was built properly by checking the version number.

```
lighthouse --version
```

Install the binary.

```bash
sudo cp $HOME/.cargo/bin/lighthouse /usr/local/bin/lighthouse
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Lighthouse Consensus Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/lighthouse bn \
  --datadir /var/lib/lighthouse \
  --network mainnet \
  --staking \
  --validator-monitor-auto \
  --metrics \
  --checkpoint-sync-url=https://beaconstate.info \
  --port 9000 \
  --quic-port 9001 \
  --http-port 5052 \
  --target-peers 100 \
  --metrics-port 8008 \
  --execution-endpoint http://127.0.0.1:8551 \
  --execution-jwt /secrets/jwtsecret

[Install]
WantedBy=multi-user.target
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus client is up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

Press `Ctrl` + `C` to exit the logs.

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Lighthouse Consensus Client Logs**

```bash
Feb 03 01:02:36.000 INFO New block received                      root: 0xb5ccb2f85d981ca9e1c0d904f967403ddf8c47532c195fe213c94a28ffaf6a2e, slot: 2138
Feb 03 01:02:42.000 INFO Synced                                  slot: 2138, block: 0x1cb281a, epoch: 121, finalized_epoch: 120, finalized_root: 0x1dce0, exec_hash: 0x6827aeb (verified), peers: 50, service: slot_notifier
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/lighthouse/beacon
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Lodestar

## Overview

{% hint style="info" %}
[Lodestar ](https://lodestar.chainsafe.io)is a Typescript implementation of the official Ethereum specification by the [ChainSafe.io](https://lodestar.chainsafe.io) team. In addition to the beacon chain client, the team is also working on 22 packages and libraries. A complete list can be found [here](https://hackmd.io/CcsWTnvRS_eiLUajr3gi9g). Finally, the Lodestar team is leading in light client research and development and has received funding from the EF and Moloch DAO for this purpose.
{% endhint %}

#### Official Links

| Subject       | Links                                                                         |
| ------------- | ----------------------------------------------------------------------------- |
| Releases      | <https://github.com/ChainSafe/lodestar/releases>                              |
| Documentation | [https://chainsafe.github.io/lodestar](https://chainsafe.github.io/lodestar/) |
| Website       | [https://lodestar.chainsafe.io](https://lodestar.chainsafe.io/)               |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/lodestar
sudo chown -R consensus:consensus /var/lib/lodestar
```

Install dependencies.

```bash
sudo apt-get install gcc g++ make git curl ccze -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ChainSafe/lodestar/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://github.com/ChainSafe/lodestar/releases/download/${LATEST_TAG}/lodestar-${LATEST_TAG}-linux-amd64.tar.gz"
	
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lodestar.tar.gz $BINARIES_URL
# Untar
tar -xzvf lodestar.tar.gz -C $HOME
# Cleanup
rm lodestar.tar.gz
```

Install the binaries.

```bash
sudo mkdir -p /usr/local/bin/lodestar
sudo mv $HOME/lodestar /usr/local/bin/lodestar
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install yarn.

```bash
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install yarn -y
```

Confirm yarn is installed properly.

```bash
yarn --version
# Should output version >= 1.22.19
```

Install nodejs.

```bash
#Download and import the Nodesource GPG key
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

#Create deb repository
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

#Run Update and Install
sudo apt-get update
sudo apt-get install nodejs -y
```

Install and build Lodestar.

```bash
mkdir -p ~/git
cd ~/git
git clone -b stable https://github.com/chainsafe/lodestar.git
cd lodestar
yarn install
yarn run build
```

Verify Lodestar was installed properly by displaying the version.

```bash
./lodestar --version
```

Sample output of a compatible version.

```
🌟 Lodestar: TypeScript Implementation of the Ethereum Consensus Beacon Chain.
  * Version: v1.8.0/stable/a4b29cf
  * by ChainSafe Systems, 2018-2022
```

Install the binaries.

```bash
sudo cp -a $HOME/git/lodestar /usr/local/bin/lodestar
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Lodestar Consensus Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
WorkingDirectory=/usr/local/bin/lodestar
ExecStart=/usr/local/bin/lodestar/lodestar beacon \
  --dataDir /var/lib/lodestar \
  --network mainnet \
  --rest.port 5052 \
  --port 9000 \
  --targetPeers 100 \
  --metrics.port 8008 \
  --metrics true \
  --checkpointSyncUrl https://beaconstate.info \
  --jwt-secret /secrets/jwtsecret \
  --execution.urls http://127.0.0.1:8551 \
  --suggestedFeeRecipient <0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the whole line beginning with

```
--suggestedFeeRecipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Lodestar Consensus Client Logs**

```bash
Mar-19 04:09:49.000    info: Synced - slot: 3338 - head: 3355 0x5abb_ac30 - execution: valid(0x1a3c_2ca5) - finalized: 0xfa22_1142:3421 - peers: 25
Mar-19 04:09:52.000    info: Synced - slot: 3339 - head: 3356 0xcd2a_8b32 - execution: valid(0xab34_fa32) - finalized: 0xfa22_1142:3421 - peers: 25
Mar-19 04:09:04.000    info: Synced - slot: 3340 - head: 3357 0xff1a_f12a - execution: valid(0xfaf1_b35f) - finalized: 0xfa22_1142:3421 - peers: 25
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/lodestar/chain-db
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Teku

## Overview

{% hint style="info" %}
[PegaSys Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) (formerly known as Artemis) is a Java-based Ethereum client designed & built to meet institutional needs and security requirements. PegaSys is an arm of [ConsenSys](https://consensys.net) dedicated to building enterprise-ready clients and tools for interacting with the core Ethereum platform. Teku is Apache 2 licensed and written in Java, a language notable for its materity & ubiquity.
{% endhint %}

{% hint style="info" %}
**Note**: Teku is configured to run both **validator client** and **beacon chain client** in one process.
{% endhint %}

#### Official Links

| Subject       | Links                                                                                                         |
| ------------- | ------------------------------------------------------------------------------------------------------------- |
| Releases      | <https://github.com/ConsenSys/teku/releases>                                                                  |
| Documentation | <https://docs.teku.consensys.net/introduction>                                                                |
| Website       | [https://consensys.net/knowledge-base/ethereum-2/teku](https://consensys.net/knowledge-base/ethereum-2/teku/) |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/teku
sudo chown -R consensus:consensus /var/lib/teku
```

Install dependencies.

```bash
sudo apt install curl ccze openjdk-21-jdk libsnappy-dev libc6-dev jq git libc6 unzip -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ConsenSys/teku/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://artifacts.consensys.net/public/teku/raw/names/teku.tar.gz/versions/${LATEST_TAG}/teku-${LATEST_TAG}.tar.gz"
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O teku.tar.gz $BINARIES_URL
# Untar
tar -xzvf teku.tar.gz -C $HOME
# Rename folder
mv teku-${LATEST_TAG} teku
# Cleanup
rm teku.tar.gz
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/teku /usr/local/bin/teku
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/ConsenSys/teku.git
cd teku
# Get new tags
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/ConsenSys/teku/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
./gradlew distTar installDist
```

Verify Teku was built properly by displaying the version.

```shell
cd $HOME/git/teku/build/install/teku/bin
./teku --version
```

Install the binaries.

```shell
sudo cp -a $HOME/git/teku/build/install/teku /usr/local/bin/teku
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

{% tabs %}
{% tab title="Standalone Beacon Node (Recommended)" %}

```shell
[Unit]
Description=Teku Beacon Node Consensus Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment=JAVA_OPTS=-Xmx6g
Environment=TEKU_OPTS=-XX:-HeapDumpOnOutOfMemoryError
ExecStart=/usr/local/bin/teku/bin/teku \
  --network=mainnet \
  --data-path=/var/lib/teku/ \
  --data-storage-mode="minimal" \
  --checkpoint-sync-url="https://beaconstate.info" \
  --ee-endpoint=http://127.0.0.1:8551 \
  --ee-jwt-secret-file=/secrets/jwtsecret \
  --rest-api-enabled=true \
  --rest-api-port=5052 \
  --p2p-port=9000 \
  --p2p-peer-upper-bound=100 \
  --p2p-peer-lower-bound=60 \
  --metrics-enabled=true \
  --metrics-port=8008 \
  --validators-proposer-default-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the line beginning with

```
--validators-proposer-default-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.
{% endtab %}

{% tab title="Combined BN+VC" %}
{% hint style="info" %}
This configuration combines the beacon chain and validator into one running service. While it is simpler to manage and run, this configuration is less flexible when it comes to running EL+CL failover nodes or in times you wish to resync your execution client and temporarily use [Rocket Pool's Rescue Node](https://rescuenode.com/docs/how-to-connect/solo).
{% endhint %}

```shell
[Unit]
Description=Teku Beacon Node + Validator Consensus Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment=JAVA_OPTS=-Xmx6g
Environment=TEKU_OPTS=-XX:-HeapDumpOnOutOfMemoryError
ExecStart=/usr/local/bin/teku/bin/teku \
  --network=mainnet \
  --data-path=/var/lib/teku/ \
  --data-storage-mode="minimal" \
  --initial-state="https://beaconstate.info" \
  --ee-endpoint=http://127.0.0.1:8551 \
  --ee-jwt-secret-file=/secrets/jwtsecret \
  --rest-api-enabled=true \
  --rest-api-port=5052 \
  --p2p-port=9000 \
  --p2p-peer-upper-bound=100 \
  --p2p-peer-lower-bound=60 \
  --metrics-enabled=true \
  --metrics-port=8008 \
  --validator-keys=/var/lib/teku/validator_keys:/var/lib/teku/validator_keys \
  --validators-graffiti="🏠🥩🪙🛡️" \
  --validators-proposer-default-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the whole three lines beginning with

```
--validator-keys
--validators-graffiti
--validators-proposer-default-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.
{% endtab %}
{% endtabs %}

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus clients are up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Consensus Client Logs**

```bash
teku[64122]: 02:24:28.010 INFO  - Slot Event  *** Slot: 19200, Block: 1468A43F874EDE790DB6B499A51003500B5BA85226E9500A7A187DB9A169DE20, Justified: 1132, Finalized: 1133, Peers: 70
teku[64122]: 02:24:40.010 INFO  - Slot Event  *** Slot: 19200, Block: 72B092AADFE146F5D3F395A720C0AA3B2354B2095E3F10DC18F0E9716D286DCB, Justified: 1132, Finalized: 1133, Peers: 70
```

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Teku Consensus Client Logs**

```bash
teku[64122]: 02:24:28.010 INFO  - Slot Event  *** Slot: 19200, Block: 1468A43F874EDE790DB6B499A51003500B5BA85226E9500A7A187DB9A169DE20, Justified: 1132, Finalized: 1133, Peers: 70
teku[64122]: 02:24:40.010 INFO  - Slot Event  *** Slot: 19200, Block: 72B092AADFE146F5D3F395A720C0AA3B2354B2095E3F10DC18F0E9716D286DCB, Justified: 1132, Finalized: 1133, Peers: 70
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/teku/beacon
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Nimbus

## Overview

{% hint style="info" %}
[Nimbus](https://our.status.im/tag/nimbus/) is a research project and a client implementation for Ethereum designed to perform well on embedded systems and personal mobile devices, including older smartphones with resource-restricted hardware. The Nimbus team are from [Status](https://status.im/about/) the company best known for [their messaging app/wallet/Web3 browser](https://status.im) by the same name. Nimbus (Apache 2) is written in Nim, a language with Python-like syntax that compiles to C.
{% endhint %}

{% hint style="info" %}
**Note**: Nimbus is configured to run both **validator client** and **beacon chain client** in one process.
{% endhint %}

#### Official Links

| Subject       | Links                                                                 |
| ------------- | --------------------------------------------------------------------- |
| Releases      | <https://github.com/status-im/nimbus-eth2/releases>                   |
| Documentation | [https://nimbus.guide](https://nimbus.guide/)                         |
| Website       | [https://our.status.im/tag/nimbus](https://our.status.im/tag/nimbus/) |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/nimbus
sudo chown -R consensus:consensus /var/lib/nimbus
```

Install dependencies.

```bash
sudo apt install curl libsnappy-dev libc6-dev jq libc6 unzip ccze -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/status-im/nimbus-eth2/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep _Linux_amd64.*.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O nimbus.tar.gz $BINARIES_URL
# Untar
tar -xzvf nimbus.tar.gz -C $HOME
# Rename folder
mv nimbus-eth2_Linux_amd64_* nimbus
# Cleanup
rm nimbus.tar.gz
```

Install the binaries, display version and cleanup.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv nimbus/build/nimbus_beacon_node /usr/local/bin
</strong>sudo mv nimbus/build/nimbus_validator_client /usr/local/bin
nimbus_beacon_node --version
rm -r nimbus
</code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install dependencies.

```bash
sudo apt-get update
sudo apt-get install curl build-essential git -y
```

Build the binary.

```bash
mkdir -p ~/git
cd ~/git
git clone -b stable https://github.com/status-im/nimbus-eth2
cd nimbus-eth2
make -j$(nproc) update
make -j$(nproc) nimbus_beacon_node
make -j$(nproc) nimbus_validator_client
```

Verify Nimbus was built properly by displaying the version.

```bash
cd $HOME/git/nimbus-eth2/build
./nimbus_beacon_node --version
```

Install the binary.

<pre class="language-bash"><code class="lang-bash"><strong>sudo cp $HOME/git/nimbus-eth2/build/nimbus_beacon_node /usr/local/bin
</strong><strong>sudo cp $HOME/git/nimbus-eth2/build/nimbus_validator_client /usr/local/bin
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

{% tabs %}
{% tab title="Standalone Beacon Node (Recommended)" %}

```shell
[Unit]
Description=Nimbus Consensus Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/nimbus_beacon_node \
  --network=mainnet \
  --data-dir=/var/lib/nimbus \
  --tcp-port=9000 \
  --udp-port=9000 \
  --max-peers=100 \
  --rest-port=5052 \
  --enr-auto-update=true \
  --non-interactive \
  --status-bar=false \
  --in-process-validators=false \
  --web3-url=http://127.0.0.1:8551 \
  --rest \
  --metrics \
  --metrics-port=8008 \
  --jwt-secret="/secrets/jwtsecret" \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

{% endtab %}

{% tab title="Combined (BN+VC)" %}
{% hint style="info" %}
This configuration combines the beacon chain and validator into one running service. While it is simpler to manage and run, this configuration is less flexible when it comes to running EL+CL failover nodes or in times you wish to resync your execution client and temporarily use [Rocket Pool's Rescue Node](https://rescuenode.com/docs/how-to-connect/solo).
{% endhint %}

```shell
[Unit]
Description=Nimbus Consensus Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/nimbus_beacon_node \
  --network=mainnet \
  --data-dir=/var/lib/nimbus \
  --tcp-port=9000 \
  --udp-port=9000 \
  --max-peers=100 \
  --rest-port=5052 \
  --enr-auto-update=true \
  --web3-url=http://127.0.0.1:8551 \
  --rest \
  --metrics \
  --metrics-port=8008 \
  --jwt-secret="/secrets/jwtsecret" \
  --graffiti="🏠🥩🪙🛡️!" \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

{% endtab %}
{% endtabs %}

* Replace `<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, use the Standalone Beacon Node configuration and delete the whole line beginning with

```
--suggested-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to quickly sync with Checkpoint Sync.

{% hint style="info" %}
Checkpoint sync allows you to start your consensus layer within minutes instead of days.
{% endhint %}

```bash
sudo -u consensus /usr/local/bin/nimbus_beacon_node trustedNodeSync \
--network=mainnet \
--trusted-node-url=https://beaconstate.info \
--data-dir=/var/lib/nimbus \
--backfill=false
```

When the checkpoint sync is complete, you'll see the following message:

> Done, your beacon node is ready to serve you! Don't forget to check that you're on the canonical chain by comparing the checkpoint root with other online sources. See <https://nimbus.guide/trusted-node-sync.html> for more information.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus clients are up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Consensus Client Logs**

```
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:00.000+00:00 Slot start       topics="beacnde" slot=31205 epoch=903 sync=synced peers=80 head=13a131:31204 finalized=1111:cdba33411 delay=69us850ns
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:08.000+00:00 Slot end         topics="beacnde" slot=31205 nextActionWait=7m27s985ms126us530ns nextAttestationSlot=31235 nextProposalSlot=-1 syncCommitteeDuties=none head=13a131:31204
```

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Nimbus Consensus Client Logs**

```bash
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:00.000+00:00 Slot start       topics="beacnde" slot=31205 epoch=903 sync=synced peers=80 head=13a131:31204 finalized=1111:cdba33411 delay=69us850ns
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:08.000+00:00 Slot end         topics="beacnde" slot=31205 nextActionWait=7m27s985ms126us530ns nextAttestationSlot=31235 nextProposalSlot=-1 syncCommitteeDuties=none head=13a131:31204
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/nimbus/db

#Perform checkpoint sync
sudo -u consensus /usr/local/bin/nimbus_beacon_node trustedNodeSync \
--network=mainnet \
--trusted-node-url=https://beaconstate.info \
--data-dir=/var/lib/nimbus \
--backfill=false

sudo systemctl restart consensus
```

With checkpoint sync, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Prysm

## Overview

{% hint style="info" %}
[Prysm](https://github.com/prysmaticlabs/prysm) is a Go implementation of Ethereum protocol with a focus on usability, security, and reliability. Prysm is developed by [Prysmatic Labs](https://prysmaticlabs.com), a company with the sole focus on the development of their client. Prysm is written in Go and released under a GPL-3.0 license.
{% endhint %}

#### Official Links

| Subject       | Links                                            |
| ------------- | ------------------------------------------------ |
| Releases      | <https://github.com/OffchainLabs/prysm/releases> |
| Documentation | <https://www.offchainlabs.com/prysm/docs>        |
| Website       | <https://www.offchainlabs.com/prysm/docs>        |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/prysm/beacon
sudo chown -R consensus:consensus /var/lib/prysm/beacon
```

Install dependencies.

```bash
sudo apt install curl jq git ccze -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest binaries.

```bash
cd $HOME
prysm_version=$(curl -f -s https://prysmaticlabs.com/releases/latest)
file_beacon=beacon-chain-${prysm_version}-linux-amd64
file_validator=validator-${prysm_version}-linux-amd64
curl -f -L "https://prysmaticlabs.com/releases/${file_beacon}" -o beacon-chain
curl -f -L "https://prysmaticlabs.com/releases/${file_validator}" -o validator
chmod +x beacon-chain validator
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv beacon-chain validator /usr/local/bin
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install Go dependencies. Latest version [available here](https://go.dev/dl/).

```bash
wget -O go.tar.gz <LATEST VERSION URL FROM ABOVE>
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go.tar.gz
echo export PATH=$PATH:/usr/local/go/bin >> $HOME/.bashrc
source $HOME/.bashrc
```

Verify Go is properly installed by checking the version and cleanup files.

```bash
go version
rm go.tar.gz
```

Install build dependencies.

```bash
sudo apt-get update
sudo apt install build-essential git
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/OffchainLabs/prysm.git
cd prysm
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/OffchainLabs/prysm/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
go build -o=./build/beacon-chain ./cmd/beacon-chain
go build -o=./build/validator ./cmd/validator
```

Install the binaries.

```shell
sudo cp $HOME/git/prysm/build/beacon-chain /usr/local/bin
sudo cp $HOME/git/prysm/build/validator /usr/local/bin
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

<pre class="language-bash"><code class="lang-bash"><strong>[Unit]
</strong>Description=Prysm Consensus Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/beacon-chain \
  --mainnet \
  --datadir=/var/lib/prysm/beacon \
  --grpc-gateway-port 5052 \
  --p2p-tcp-port 13000 \
  --p2p-udp-port 12000 \
  --p2p-max-peers 80 \
  --monitoring-port 8008 \
  --checkpoint-sync-url=https://beaconstate.info \
  --execution-endpoint=http://localhost:8551 \
  --jwt-secret=/secrets/jwtsecret \
  --accept-terms-of-use=true \
  --suggested-fee-recipient=&#x3C;0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
</code></pre>

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the whole lines beginning with

```
--suggested-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus clients are up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Consensus Client Logs**

```bash
"Peer summary" activePeers=69 inbound=0 outbound=69 prefix=p2p
"Synced new block" block=0xb5ccb2f85... epoch=1837 finalizedEpoch=1838 finalizedRoot=0x1dce0... prefix=blockchain slot=21338 "Finished applying state transition" attestations=128 payloadHash=0x000000000000 prefix=blockchain slot=2138 syncBitsCount=213 txCount=0"terminal difficulty has not been reached yet" latestDifficulty=10000000 prefix=powchain terminalDifficulty=10000000
```

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Prysm Consensus Client Logs**

```bash
time="2023-02-02 11:21:00" level=info msg="Peer summary" activePeers=35 inbound=10 outbound=25 prefix=p2p
time="2023-02-02 11:21:00" level=info msg="Synced new block" block=0xd9ddeza1289... epoch=11795 finalizedEpoch=111794 finalizedRoot=0x462e3275... prefix=blockchain slot=31205
time="2023-02-02 11:21:00" level=info msg="Finished applying state transition" attestations=64 payloadHash=0x000000000000 prefix=blockchain slot=31205 syncBitsCount=209 txCount=0
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/prysm/beacon/beaconchaindata
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Step 5: Installing Validator


# Setting up Validator Keys

## :seedling: 1. Obtain ETH

To make the deposit transaction(s), you will want your 32 ETH, or multiples, in a single hardware wallet address.

{% hint style="info" %}
Every 32 ETH you own allows you to make 1 validator. You can run thousands of validators with your node.
{% endhint %}

## :key: 2. Generate validator keys

#### Before continuing please have the following:

* [ ] **Hardware wallet address or** [**Safe multisig wallet**](https://app.safe.global/welcome) **address**: This is for your [Withdrawal Address](https://notes.ethereum.org/@launchpad/withdrawals-faq#Q-What-are-the-two-types-of-withdrawals). It must be in checksum format, which means some letters are UPPERCASE. If needed, validate your address's checksum format against a block explorer, such as <https://etherscan.io>
* [ ] **Browser dApp Wallet** (i.e. Metamask) with 32 Ethers for each validator

<figure><img src="/files/yB0epV8Qy58GprdIYQjM" alt=""><figcaption><p>Example of Vitalik's address in checksum format</p></figcaption></figure>

#### Before continuing please understand the following:

* [ ] The **Withdrawal Address** is:
  * where your ETH is returned upon "voluntary exiting a validator", or also known as full withdrawal.
  * where you receive partial withdrawals, which is where any excess balance above 32 ETH is periodically scraped and made available for use.
* [ ] As this is **permanent** once set, **triple check** your address.
* [ ] DO NOT USE AN :octagonal\_sign: **EXCHANGE ADDRESS** :octagonal\_sign: AS WITHDRAWAL ADDRESS.

{% hint style="warning" %}
**Offline Key Generation Best Practices**: The mnemonic seed (24 words) to your validator should be protected by keeping them offline. Use Tails OS (see option 3) or a [Linux Live USB](https://www.youtube.com/watch?v=oDELXYNSS5w)(Option 1) or Wagyu to generate keys.&#x20;

If this is not possible, at least physically disconnect from the network by unplugging ethernet cable or disconnecting from Wifi.
{% endhint %}

Ways to create your validator keys:

<details>

<summary>Option 1 for Ubuntu - ethstaker_deposit-cli</summary>

#### 1. Download ethstaker\_deposit-cli from Github.

```bash
#Install dependencies
sudo apt install jq curl -y

#Setup variables
RELEASE_URL="https://api.github.com/repos/eth-educators/ethstaker-deposit-cli/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-amd64.tar.gz$)"
BINARY_FILE="ethstaker_deposit-cli.tar.gz"

echo "Downloading URL: $BINARIES_URL"

cd $HOME
#Download binary
wget -O $BINARY_FILE $BINARIES_URL
#Extract archive
tar -xzvf $BINARY_FILE -C $HOME
#Rename
mv ethstaker_deposit*amd64 ethstaker_deposit-cli
cd ethstaker_deposit-cli
```

#### 2. Make a new mnemonic

Replace `<HARDWARE_WALLET_ADDRESS>` with withdrawal address.

```
./deposit new-mnemonic --chain mainnet --execution_address <HARDWARE_WALLET_ADDRESS>
```

* Choose your language
* Repeat your withdrawal/execution address for confirmation
* Choose the language of the mnemonic word list
* Choose how many new validators you wish to run
* Create a **keystore password** that secures your validator keystore files
* Repeat your **keystore password** for confirmation
* Answer yes if you want to generate compounding 0x02 validator
* Write down your 24 word mnemonic seed
* Type your mnemonic, first 4 letters is enough

You will see the following messages after successfully generated the keystore(s) and the deposit(s):

<pre class="language-bash"><code class="lang-bash"><strong>
</strong>                  #####     #####
                ##     #####     ##
    ###         ##   #######     #########################
    ##  ##      #####               ##                   ##
    ##     #####                 ##                       ##
    ##     ##                     ##                      ###
   ########                        ##                     ####
   ##        ##   ###         #####                       #####
   #                          ##                         # #####
   #                            #                        #  #####
   ##                             ##                    ##
   ##                              ##                   ##
   ##             ###              ##                   ##
   ###############                 ##                   ##
   ###               ##                                 ##
      #############################                    ##
                     ##                             ###
                     #######     #################     ###
                     ##   ## ##        ##   ##    ###
                     ##############          #############

Creating your keys:               [####################################]  &#x3C;N>/&#x3C;N>
Creating your keystores:          [####################################]  &#x3C;N>/&#x3C;N>
Verifying your keystores:         [####################################]  &#x3C;N>/&#x3C;N>
Verifying your deposits:          [####################################]  &#x3C;N>/&#x3C;N>

Success!
Your keys can be found at: /home/username/ethstaker_deposit-cli/validator_keys
</code></pre>

</details>

<details>

<summary>Option 2 for Windows/Linux/Mac - Wagyu GUI</summary>

**Wagyu** is an application aimed at lowering the technical bar to staking on Ethereum.

As a 'one-click installer', it provides a clean UI automating the setup and management of all the infrastructure necessary to stake without the user needing to have any technical knowledge.

**Download Wagyu**: [https://wagyu.gg](https://wagyu.gg/)

1. Click create new secret recovery phrase
2. Select your network
3. Click create
4. Write down your 24 word secret recovery phrase
5. Check your phrase to confirm you copied it correctly
6. Specify number of new keys to generate
7. Specify your keystore password
8. Specify your Withdrawal address
9. Click next
10. Re-type your keystore password
11. Browse to where you want to save your keys
12. Review information and close

</details>

<details>

<summary>Option 3 - Offline Tails with ethstaker_deposit-cli</summary>

You will learn how to boot up a windows PC into an airgapped [Tails operating system](https://tails.boum.org/index.en.html).

The Tails OS is an *amnesic* operating system, meaning it will save nothing and *leave no tracks behind* each time you boot it.

#### **1. Prerequisites**

You need:

* 2 storage mediums (can be USB stick, SD cards or external hard drives)
* One of them must be > 8GB
* Windows or Mac computer
* 30 minutes or longer depending on your download speed

#### **2. Download Tails OS**

Download the official image from the [Tails website](https://tails.boum.org/install/index.en.html). Might take a while, go grab a coffee.

Make sure you follow the guide on the Tails website to verify your download of Tails.

#### **3. Download and install the software to transfer your Tails image on your USB stick**

For Windows, use one of

* [Etcher](https://tails.boum.org/etcher/Etcher-Portable.exe)
* [Win32 Disk Imager](https://win32diskimager.org/#download)
* [Rufus](https://rufus.ie/en_US/)

For Mac, download [Etcher](https://tails.boum.org/etcher/Etcher.dmg)

#### **4. Making your bootable USB stick**

Run the above software. This is an example how it looks like on Mac OS with etcher, but other software should be similar.

<img src="/files/-MbF9sxqVx2RPyZpErai" alt="" data-size="original">

Select the Tails OS image that you downloaded as the image. Then select the USB stick (the larger one).

Then flash the image to the larger USB stick.

#### **5. Download and verify the ethstaker\_deposit-cli**

Download the latest ethstaker\_deposit-cli binary by referring to Option 1's steps.

Copy the file to the other USB stick.

#### **6. Reboot your computer and into Tails OS**

After you have done all the above, you can reboot. If you are connected by a LAN cable to the internet, you can disconnect it manually.

Plug in the USB stick that has your Tails OS.

On Mac, press and hold the Option key immediately upon hearing the startup chime. Release the key after Startup Manager appears.

On Windows, it depends on your computer manufacturer. Usually it is by pressing F1 or F12. If it doesn't work, try googling "Enter boot options menu on \[Insert your PC brand]"

Choose the USB stick that you loaded up with Tails OS to boot into Tails.

#### **7. Welcome to Tails OS**

<img src="/files/-MbF9vA__yS_1qRPxmPL" alt="" data-size="original">

You can boot with all the default settings.

#### **8. Run** ethstaker\_deposit-cli

Plug in your other USB key with the `ethstaker_deposit-cli` file.&#x20;

Locate the USB key, mount the drive and add execute permissions.

```bash
# Locate the usb key
sudo fdisk -l
# Create a mount point
sudo mkdir -p /media/usb-drive
# Mount the usb key. Change device name
sudo mount /dev/sda1 /media/usb-drive
# Change directories
cd /media/usb-drive/ethstaker_deposit-cli
# Add execute permissions
sudo chmod +x ./deposit
```

#### 9. Make a new mnemonic

Replace `<HARDWARE_WALLET_ADDRESS>` with withdrawal address.

```
./deposit new-mnemonic --chain mainnet --execution_address <HARDWARE_WALLET_ADDRESS>
```

* Choose your language
* Repeat your withdrawal/execution address for confirmation
* Choose the language of the mnemonic word list
* Choose how many new validators you wish to run
* Create a **keystore password** that secures your validator keystore files
* Repeat your **keystore password** for confirmation
* Answer yes if you want to generate compounding 0x02 validator
* Write down your 24 word mnemonic seed
* Type your mnemonic, first 4 letters is enough

You will see the following messages after successfully generated the keystore(s) and the deposit(s):

<pre class="language-bash"><code class="lang-bash"><strong>
</strong>                  #####     #####
                ##     #####     ##
    ###         ##   #######     #########################
    ##  ##      #####               ##                   ##
    ##     #####                 ##                       ##
    ##     ##                     ##                      ###
   ########                        ##                     ####
   ##        ##   ###         #####                       #####
   #                          ##                         # #####
   #                            #                        #  #####
   ##                             ##                    ##
   ##                              ##                   ##
   ##             ###              ##                   ##
   ###############                 ##                   ##
   ###               ##                                 ##
      #############################                    ##
                     ##                             ###
                     #######     #################     ###
                     ##   ## ##        ##   ##    ###
                     ##############          #############

Creating your keys:               [####################################]  &#x3C;N>/&#x3C;N>
Creating your keystores:          [####################################]  &#x3C;N>/&#x3C;N>
Verifying your keystores:         [####################################]  &#x3C;N>/&#x3C;N>
Verifying your deposits:          [####################################]  &#x3C;N>/&#x3C;N>

Success!
Your keys can be found at: /home/username/ethstaker_deposit-cli/validator_keys
</code></pre>

**Result**: a folder called `validator_keys` containing keystore-m files and deposit\_data.json

If you ran this command directly from your non-Tails USB stick, the validator keys should stay on it.&#x20;

If it hasn't, copy the directory over to your non-Tails USB stick.

Confirm your validator\_keys are on the USB stick before leaving.

```bash
ls /media/usb-drive/ethstaker_deposit-cli/validator_keys
```

:fire: Make sure you have saved your validator keys directory in your other USB stick (non Tails OS) before you shutdown Tails. Tails will delete everything saved on it after you shutdown.

:tada: Congrats on learning how to use Tails OS to make an air gapped system.

</details>

### Result: There are two types of files generated.

| File type                                                             | Purpose                                                                                                                                                                                                                                        |
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>Keystore file(s)</p><p>\[i.e.. keystore-16945983.json]</p>         | <ul><li>Controls the validator's ability to sign transactions</li><li>Imported and loaded into your validator</li><li>Keep private. Do not share with anyone</li><li>Can be recreated from your mnemonic seed/secret recovery phrase</li></ul> |
| <p>Deposit data file(s)</p><p>\[i.e. deposit\_data-16945983.json]</p> | <ul><li>Public information about your validator</li><li>Required to execute your deposit through the Ethereum Launchpad</li><li>Can be recreated from your mnemonic seed/secret recovery phrase</li></ul>                                      |

## :arrow\_up: 3. Transfer validator keys to node

{% hint style="info" %}
**Local node**: Skip this step if you generated your keys on your node with **ethstaker\_deposit-cli**. No need to transfer as they're already there.
{% endhint %}

After creating the validator keys offline, you'll want to copy these validator keys to your node.

To align with this guide's steps, make the default validator\_keys path on your node.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir -p $HOME/ethstaker_deposit-cli/validator_keys
</strong></code></pre>

To transfer validator key files to your node from your local computer, consider using:

<details>

<summary>Option 1 - File Transfer</summary>

* File transfer
  * Windows OS - use [WinSCP](https://winscp.net) or [FileZilla](https://filezilla-project.org/download.php?type=client)
  * Mac or Linux - use [FileZilla](https://filezilla-project.org/download.php?type=client) or [SFTP](https://www.digitalocean.com/community/tutorials/how-to-use-sftp-to-securely-transfer-files-with-a-remote-server) or [rsync](https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/)

Transfer the **keystore-m\_xxxxxxxx.json** files to the following location on your node.

```bash
$HOME/ethstaker_deposit-cli/validator_keys
```

</details>

<details>

<summary>Option 2 - USB Key</summary>

### **Step 1: From OFFLINE machine, copy validator keys to a USB key.**

Plug the USB key into offline machine, then locate the device name.

```bash
# Locate the usb key
sudo fdisk -l
```

Upon executing the above command you will get an output similar to the one below:

```bash
Disk /dev/sdc: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start      End  Sectors  Size Id Type
/dev/sdc1  *     8192 15555555 25555555 7.4G  b W95 FAT32
```

Mount the key. Change the device name accordingly.

```bash
# Create a mount point
sudo mkdir -p /media/usb-drive
# Mount the usb key
sudo mount /dev/sdc1 /media/usb-drive
```

Copy the keys. Adjust the path names if needed.

```bash
# Create a directory on the usb drive to copy the keys into
sudo mkdir -p /media/usb-drive/ethstaker_deposit-cli/validator_keys
# Copy the keys to the usb drive
sudo cp $HOME/ethstaker_deposit-cli/validator_keys/*.json /media/usb-drive/ethstaker_deposit-cli/validator_keys
# Cleanup
sudo umount /media/usb-drive
```

### **Step 2: From a USB key,  copy validator keys to the NODE.**

Plug the USB key into node, then locate the device name.

```bash
# Locate the usb key
sudo fdisk -l
```

Upon executing the above command you will get an output similar to the one below:

```bash
Disk /dev/sdc: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start      End  Sectors  Size Id Type
/dev/sdc1  *     8192 15555555 25555555 7.4G  b W95 FAT32
```

Mount the key. Change the device name accordingly.

```bash
# Create a mount point
sudo mkdir -p /media/usb-drive
# Mount the usb key
sudo mount /dev/sdc1 /media/usb-drive
```

Copy the keys. Adjust the path names if needed.

```bash
# Create a directory copy the keys into
sudo mkdir -p $HOME/ethstaker_deposit-cli/validator_keys
# Copy the keys to the default path
sudo cp /media/usb-drive/ethstaker_deposit-cli/validator_keys/*.json $HOME/ethstaker_deposit-cli/validator_keys
# Cleanup
sudo umount /media/usb-drive
```

</details>

After transferring the files, verify that the keystore-m files are in the proper location on your node.

```bash
ls -l $HOME/ethstaker_deposit-cli/validator_keys
```

Expected sample output:

```bash
-r--r----- 1 ethereum ethereum 706 Oct  1 02:33 deposit_data-1696645983.json
-r--r----- 1 ethereum ethereum 710 Oct  1 02:33 keystore-m_12381_3600_0_0_0-161664283.json
```

## :woman\_technologist: 4. Deposit transactions at the Launchpad

{% hint style="warning" %}
Only deposit the 32 ETH per validator if you are confident your node will be fully synced, which takes on average a day - check your logs, and ready to perform validator duties. You can return later to launchpad with your deposit-data to finish the next steps.
{% endhint %}

1. Follow the walk-through at the Launchpad: [https://launchpad.ethereum.org](https://launchpad.ethereum.org/)
2. Upload your`deposit_data-#########.json` found in the `validator_keys` directory.
3. Connect the launchpad with your wallet, review and accept terms. Ensure you're connected to **Mainnet** network.

{% hint style="info" %}
:whale: **Batch Depositing Tip**: If you have many deposits to make for many validators, consider using [Abyss.finance's eth2depositor tool.](https://abyss.finance/eth2depositor) This greatly improves the deposit experience as multiple deposits can be batched into one transaction, thereby saving gas fees and saving your fingers by minimizing Metamask clicking.

Source: <https://twitter.com/AbyssFinance/status/1379732382044069888>
{% endhint %}

4. Confirm the transaction(s). There's one deposit transaction of 32 ETH for each validator.

* **Deposit Example**: If you want to run 3 validators you will need to have (32 x 3) = 96 ETH plus some extra to cover the gas fees.
* **Verify Deposit Contract:** Your transaction is depositing ETH to the [official deposit contract address.](https://blog.ethereum.org/2020/11/04/eth2-quick-update-no-19/) **Check**, *double-check*, ***triple-check*** that the official Ethereum Deposit Contract address is correct. [`0x00000000219ab540356cBB839Cbe05303d7705Fa`](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa)
* **Ledger Nano Hardware wallet users**: If you encounter difficulty making the deposit transaction, enable blind signing and contract data.

## 4. Review backups

{% hint style="danger" %}
:fire: **Critical Crypto Reminder:** **Keep your mnemonics, keep your ETH.**

* **Stay Offline**: Write down your mnemonic seed **offline**. *Not email. Not cloud.*
* **More than 1 backup of mnemonic**: Multiple copies with multiple locations is better. *Best stored in a* [*metal seed.*](https://jlopp.github.io/metal-bitcoin-storage-reviews/)
* **Verify your hardware wallet's backup:** Most important of all data, this is where your withdrawal address belongs and ultimately controls the 32 ETH
* **In case of recovery**: Stored on a USB key, keep copies of&#x20;
  * `validator_keys directory` - contains all the keystore .json files
  * keystore password - used to encrypt keystore files
    {% endhint %}

#### :tada:Validator key setup and deposits are complete!


# Installing Validator


# Lighthouse

Create a service user for the validator service and create data directories.

```bash
sudo adduser --system --no-create-home --group validator
sudo mkdir -p /var/lib/lighthouse/validators
```

Import your validator keys by importing your **keystore file**. Be sure to enter your **keystore password** correctly.

```bash
sudo lighthouse account validator import \
  --network mainnet \
  --datadir /var/lib/lighthouse \
  --directory=$HOME/ethstaker_deposit-cli/validator_keys \
  --reuse-password
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Verify that your keystore file was imported successfully.

<pre class="language-bash"><code class="lang-bash"><strong>sudo lighthouse account_manager validator list \
</strong><strong>  --network mainnet \
</strong>  --datadir /var/lib/lighthouse
</code></pre>

Once successful, you will be shown your **validator's public key**.

For example, `0x8d9138fcf5676e2031dc4eae30a2c92e3306903eeec83ca83f4f851afbd4cb3b33f710e6f4ac516b4598697b30b04302`

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/lighthouse/validators
sudo chmod 700 /var/lib/lighthouse/validators
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.&#x20;

```bash
[Unit]
Description=Lighthouse Validator Client service for mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/lighthouse vc \
  --network mainnet \
  --beacon-nodes http://localhost:5052 \
  --datadir /var/lib/lighthouse \
  --graffiti="🏠🥩🪙🛡️" \
  --metrics \
  --metrics-port 8009 \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a graffiti message that is included when you produce a block, add your message between the double quotes after `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
INFO Enabled validator          voting_pubkey: 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf, signing_method: local_keystore
INFO Enabled validator          voting_pubkey: 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866, signing_method: local_keystore
INFO Initialized validators     enabled: 2, disabled: 0
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Lighthouse Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`INFO Successfully published attestations`".

```
Feb 08 01:01:0 INFO Successfully published attestations type: unaggregated, slot: 12422, committee_index: 3, head_block: 0xabc111daedf1281..., validator_indices: [12345], count:1, service: attestation 
Feb 08 01:01:30 INFO Connected to beacon node(s) synced: 1, available: 1, total: 1, service: notifier
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Lodestar

Setup a Lodestar validator client

Create a service user for the validator service, as this improves security, then create data directories.

<pre class="language-bash"><code class="lang-bash">sudo adduser --system --no-create-home --group validator
<strong>sudo mkdir -p /var/lib/lodestar/validators
</strong></code></pre>

Import your validator keys by importing your **keystore file**. Be sure to enter your **keystore password** correctly.

```bash
cd /usr/local/bin/lodestar
sudo ./lodestar validator import \
  --network mainnet \
  --dataDir="/var/lib/lodestar/validators" \
  --keystore=$HOME/ethstaker_deposit-cli/validator_keys
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Verify that your keystore file was imported successfully.

```bash
sudo ./lodestar validator list \
  --network mainnet \
  --dataDir="/var/lib/lodestar/validators"
```

Once successful, you will be shown your **validator's public key**.

For example, `0x8d9138fcf5676e2031dc4eae30a2c92e3306903eeec83ca83f4f851afbd4cb3b33f710e6f4ac516b4598697b30b04302`

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/lodestar/validators
sudo chmod 700 /var/lib/lodestar/validators
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.

```bash
[Unit]
Description=Lodestar Validator Client service for mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=300
WorkingDirectory=/usr/local/bin/lodestar
ExecStart=/usr/local/bin/lodestar/lodestar validator \
  --network mainnet \
  --dataDir /var/lib/lodestar/validators \
  --beaconNodes http://127.0.0.1:5052 \
  --metrics true \
  --metrics.port 8009 \
  --graffiti "🏠🥩🪙🛡️" \
  --suggestedFeeRecipient <0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>
  
[Install]
WantedBy=multi-user.target
```

* Replace`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a graffiti message that is included when you produce a block, add your message between the double quotes after `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
info: 100% of local keystores imported. current=2 total=2 rate=975.61keys/m
info: 2 local keystores
info: 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf
info: 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Lodestar Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`info: Published attestations`".

```bash
Feb-1  03:33:30.228     info: Published aggregateAndProofs slot=2662, index=13, count=1
Feb-1  03:37:48.393     info: Published attestations slot=2699, index=20, count=1
Feb-1  03:46:36.450     info: Published attestations slot=2713, index=2, count=1
Feb-1  03:53:48.944     info: Published attestations slot=2765, index=21, count=1
Feb-1  04:01:48.812     info: Published attestations slot=2809, index=17, count=1
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Teku

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Storing your **keystore password** in a text file is required so that Teku can decrypt and load your validators automatically.

Create a temporary file to store your **keystore password**. Type your password in this file.

```bash
sudo nano $HOME/validators-password.txt
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Confirm that your **keystore password** is correct.

```bash
sudo cat $HOME/validators-password.txt
```

When specifying directories for your validator-keys, Teku expects to find identically named keystore and password files.

For example `keystore-m_12221_3600_1_0_0-11222333.json` and `keystore-m_12221_3600_1_0_0-11222333.txt`

Run the following command to create a corresponding password file for every one of your validators.

```bash
for f in $HOME/ethstaker_deposit-cli/validator_keys/keystore*.json; do sudo cp $HOME/validators-password.txt $HOME/ethstaker_deposit-cli/validator_keys/$(basename $f .json).txt; done
```

Select a tab for your Teku configuration, either **Standalone Validator (Recommended)** or **Combined Beacon Node with Validator**. Running a standalone validator configuration is recommended for best modularity and redundancy.

{% tabs %}
{% tab title="Standalone Validator (Recommended)" %}
Copy your `validator_keys` to the data directory.

```bash
sudo mkdir -p /var/lib/teku_validator/validator_keys
sudo cp $HOME/ethstaker_deposit-cli/validator_keys/keystore* /var/lib/teku_validator/validator_keys
```

Create a service user for the validator service, then create data directories and setup ownership permissions, including hardening the access to this directory.

```bash
sudo adduser --system --no-create-home --group validator
sudo chown -R validator:validator /var/lib/teku_validator
sudo chmod -R 700 /var/lib/teku_validator
```

Verify that your validator's keystore .json files and validator's passwords .txt files are present by checking the following directory.

```bash
sudo ls -l /var/lib/teku_validator/validator_keys
```

Example output of two validator's keystore.json files with matching password.txt files.

```
-rwx------ 1 validator validator 710 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.json
-rwx------ 1 validator validator  43 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.txt
-rwx------ 1 validator validator 710 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.json
-rwx------ 1 validator validator  43 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.txt
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.&#x20;

```bash
[Unit]
Description=Teku Validator Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/teku/bin/teku validator-client \
  --network=mainnet \
  --data-path=/var/lib/teku_validator \
  --validator-keys=/var/lib/teku_validator/validator_keys:/var/lib/teku_validator/validator_keys \
  --beacon-node-api-endpoint=http://localhost:5052 \
  --validators-proposer-default-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS> \
  --validators-graffiti="🏠🥩🪙🛡️" \
  --metrics-enabled=true \
  --metrics-port=8009

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a short message that is included when you produce a block, add your message to the `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

{% endtab %}

{% tab title="Combined BN+VC" %}
{% hint style="info" %}
**Note**: Teku is configured to run both **validator client** and **beacon chain client** in one process.
{% endhint %}

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R consensus:consensus /var/lib/teku/
sudo chmod -R 700 /var/lib/teku/validator_keys
```

Copy your `validator_keys` to the data directory.

```bash
sudo mkdir -p /var/lib/teku/validator_keys
sudo cp $HOME/ethstaker_deposit-cli/validator_keys/keystore* /var/lib/teku/validator_keys
```

Verify that your validator's keystore .json files and validator's passwords .txt files are present by checking the following directory.

```bash
sudo ls -l /var/lib/teku/validator_keys
```

Example output of two validator's keystore.json files with matching password.txt files.

```
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.txt
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.txt
```

Finally, restart Teku to use the new validators.

```bash
sudo systemctl restart consensus
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu consensus | ccze
```

{% endtab %}
{% endtabs %}

For example when using 2 validators, logs will show the following:

```bash
INFO  - Loading 2 validator keys...
INFO  - Loaded 2 Validators: 95d3986, 82b225f
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Teku Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`Validator *** Published attestation`".

```bash
teku[65367]: 03:50:51.761 INFO  - Validator cc1f3ade status is active_ongoing.
teku[65367]: 03:50:52.203 INFO  - Validator   *** Published attestation        Count: 1, Slot: 31362, Root: 90FC0DF4D5958E469134A015203B53B3FB94A0FC1038FB2462882906D4A729A2
```

Delete the temporary **keystore password** file.

```bash
sudo rm $HOME/validators-password.txt
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Nimbus

Select a configuration for Nimbus. Running a standalone validator configuration is recommended for best modularity and redundancy.

{% tabs %}
{% tab title="Standalone Validator (Recommended)" %}
Create a service user for the validator service, as this improves security, then create data directories.

<pre class="language-bash"><code class="lang-bash">sudo adduser --system --no-create-home --group validator
<strong>sudo mkdir -p /var/lib/nimbus_validator
</strong></code></pre>

The following command will import your validator keys.

Enter your **keystore password** to import accounts.

```bash
sudo /usr/local/bin/nimbus_beacon_node deposits import \
  --data-dir=/var/lib/nimbus_validator $HOME/ethstaker_deposit-cli/validator_keys
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Now you can verify the accounts were imported successfully by doing a directory listing.

```bash
sudo ls -l /var/lib/nimbus_validator/validators
```

You should see a folder named for each of your validator's pubkey.

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.

```bash
[Unit]
Description=Nimbus Validator Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/nimbus_validator_client \
  --data-dir=/var/lib/nimbus_validator \
  --metrics \
  --metrics-port=8009 \
  --beacon-node=http://127.0.0.1:5052 \
  --non-interactive \
  --graffiti="🏠🥩🪙🛡️" \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>
  
[Install]
WantedBy=multi-user.target
```

* Replace`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a short message that is included when you produce a block, add your message to the `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/nimbus_validator
sudo chmod -R 700 /var/lib/nimbus_validator
```

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

{% endtab %}

{% tab title="Combined (BN+VC)" %}
{% hint style="info" %}
**Note**: In the combined configuration, Nimbus runs both **validator client** and **beacon chain client** in one systemd service process.
{% endhint %}

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R consensus:consensus /var/lib/nimbus
sudo chmod -R 700 /var/lib/nimbus
```

Finally, restart Nimbus to use the new validators.

```bash
sudo systemctl restart consensus
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu consensus | ccze
```

{% endtab %}
{% endtabs %}

For example when using 2 validators, logs will show the following:

```bash
Loading validators             topics="beacval" validatorsDir=/var/lib/nimbus/validators keystore_cache_available=true
Local validator attached       topics="val_pool" pubkey=95d39860a0d6ea3b92cba78069d21f3a validator=95d39860 initial_fee_recipient=81ba8d5c4ae850
Local validator attached       topics="val_pool" pubkey=82b225f66476962b161ed015786df00f validator=82b225f6 initial_fee_recipient=81ba8d5c4ae850
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Nimbus Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`Attestation sent`".

```bash
nimbus_beacon_node[292966]: INF 2023-02-05 01:25:26.263+00:00 Attestation sent      attestation="(aggregation_bits: 0b00000000000000000000000000000000000000000000000000000000, data: (slot: 31235, index: 3, beacon_block_root: \"ca3213f1\", source: \"1901:9deza1289\", target: \"1901:6ab1fafff\"), signature: \"32173064\")" delay=46ms543us294ns subnet_id=20
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Prysm

Create a service user for the validator service, as this improves security, then create data directories.

<pre class="language-bash"><code class="lang-bash">sudo adduser --system --no-create-home --group validator
<strong>sudo mkdir -p /var/lib/prysm/validators
</strong></code></pre>

Storing your **keystore password** in a text file is required so that Prysm can decrypt and load your validators automatically.

Create a file to store your **keystore password**. Type your password in this file.

<pre class="language-bash"><code class="lang-bash"><strong>sudo nano /var/lib/prysm/validators/password.txt
</strong></code></pre>

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Confirm that your **keystore password** is correct.

```bash
sudo cat /var/lib/prysm/validators/password.txt
```

Import your validator keys by importing your **keystore file**. When asked to create a new wallet password, enter your **keystore password**. When prompted for the imported accounts password, enter your **keystore password** again.

```bash
sudo /usr/local/bin/validator accounts import \
  --accept-terms-of-use \
  --mainnet \
  --wallet-dir=/var/lib/prysm/validators \
  --keys-dir=$HOME/ethstaker_deposit-cli/validator_keys
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Verify that your keystore file was imported successfully.

<pre class="language-bash"><code class="lang-bash"><strong>sudo /usr/local/bin/validator accounts list \
</strong>  --wallet-dir=/var/lib/prysm/validators \
  --mainnet
</code></pre>

Once successful, you will be shown your **validator's public key**. For example:

```
Showing 2 validator accounts
View the eth1 deposit transaction data for your accounts by running `validator accounts list --show-deposit-data`

Account 0 | gently-learning-chamois
[validating public key] 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866

Account 1 | presumably-powerful-lynx
[validating public key] 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf
```

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/prysm/validators
sudo chmod 700 /var/lib/prysm/validators
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.

```bash
[Unit]
Description=Prysm Validator Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/validator \
  --mainnet \
  --accept-terms-of-use \
  --datadir=/var/lib/prysm/validators \
  --beacon-rpc-provider=localhost:4000 \
  --beacon-rpc-gateway-provider=localhost:5052 \
  --wallet-dir=/var/lib/prysm/validators \
  --wallet-password-file=/var/lib/prysm/validators/password.txt \
  --graffiti="🏠🥩🪙🛡️" \
  --monitoring-port=8009 \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replace`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a graffiti message that is included when you produce a block, add your message between the double quotes after `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
level=info msg="Validating for public key" prefix=validator publicKey=0x95d39860a0d6
level=info msg="Validating for public key" prefix=validator publicKey=0x82b225f66476
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Prysm Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`INFO validator: Submitted new attestations`".

```bash
[2022-11-21 1:21:21]  INFO validator: Submitted new attestations AggregatorIndices=[12412] AttesterIndices=[73613] BeaconBlockRoot=0xca3213f1a3 CommitteeIndex=12 Slot=12422 SourceEpoch=12318 SourceRoot=0xd9ddeza1289 TargetEpoch=121231 TargetRoot=0xff313419acaa1
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Next Steps

{% hint style="success" %}
:tada: Congrats! You've finished the primary steps of setting up your validator. You're now an Ethereum staker!
{% endhint %}

## :track\_next: FAQ

<details>

<summary>Wen staking rewards?</summary>

**Activation Queue**: Once your EL+CL is synced, validator up and running, you just wait for activation. This process can take 24+ hours. Only 900 new validators can join per day. Check the queue length: [https://wenmerge.com ](<https://wenmerge.com >)

**Activated**: When you're activated, your validator will begin creating and voting on blocks while earning staking rewards.

**Quick monitoring**: Use [https://beaconcha.in/](https://beaconcha.in) to create alerts and track your validator's performance.

</details>

<details>

<summary>Sync Timeline</summary>

Syncing the consensus client is instantaneous with checkpoint sync but the execution client can take up to a day. On nodes with fast NVME drives and gigabit internet, expect your node to be fully synced in a few hours.

**How do I know I'm fully synced?**

* Check your execution client's logs and compare the block number against the most recent block on [https://etherscan.io](https://etherscan.io/)
  * Check EL logs: `journalctl -fu execution`
* Thanks to checkpoint sync, your consensus client's is instantly synched. You can compare the slot number against the most recent slot on [https://beaconcha.in](https://beaconcha.in/)
  * Check CL logs: `journalctl -fu consensus`

</details>

### :thumbsup: Recommended Next Steps

* :rocket: **Install** [**EthPillar**](/coins/overview-eth/ethpillar):  your node's buddy for easy and fast node management! Update your software with a keystroke.

#### :arrow\_forward: EthPillar Quickstart: Ubuntu One-liner Install <a href="#quickstart-ubuntu-one-liner-install" id="quickstart-ubuntu-one-liner-install"></a>

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

* :newspaper2:**Subscribe to your Execution Client and Consensus Client's Github repository**: Be notified of new releases. Find the Github links on each EL/CL's Overview section. At your EL or CL's github page while logged in, click the **Watch** button > **Custom** > click the checkbox for "**Release**".
* :smile:**Join Community**: Join the [community on Discord and Reddit](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/joining-the-community-on-discord-and-reddit#discord) to discuss all things staking related.
* :tools:**Node** **Maintenance**: Familiarize yourself with [Part II - Maintenance](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance) section, as you'll need to keep your staking node running at its best.
* :books:**Study** [**EthStaker Knowledge Base**](https://docs.ethstaker.cc/ethstaker-knowledge-base/): Increase your staking understanding
* :cd:**Backups**: Review your staking validator backups!
* :fingers\_crossed:**Finished with staking?** Before decommissioning your validator, it's good practice to properly [exit your validator](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/voluntary-exiting-a-validator) and re-claim your ETH deposit.

### :checkered\_flag: Optional Steps

* :robot:**MEV-boost**: Setup [MEV-boost](/coins/overview-eth/mev-boost) for extra staking rewards!
* :bar\_chart:**Monitoring**: Setup [Monitoring with Grafana and Prometheus](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/monitoring-your-validator-with-grafana-and-prometheus)
* :chains:**RPC**: Setup using your own [Node as a RPC endpoint](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/using-staking-node-as-rpc-url-endpoint).
* :mobile\_phone:**Notifications**: Setup [Mobile App Notifications and Monitoring by beaconcha.in](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/mobile-app-node-monitoring-by-beaconchain)
* :up:**External Monitoring**: Setup [External Monitoring with Uptime Check by Google Cloud](/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/monitoring-with-uptime-check-by-google-cloud)
* :books:**Knowledge**: Familiarize yourself with [Part III - Tips](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips) section, as you dive deeper into staking.

### :telephone: **Need extra live support?**

* Find Ethstaker frens on the [Ethstaker](https://discord.io/ethstaker) Discord and [coincashew](https://discord.gg/dEpAVWgFNB) Discord.
* Use reddit: [r/Ethstaker](https://www.reddit.com/r/ethstaker/), or [DMs](https://www.reddit.com/user/coincashew), or [r/coincashew](https://www.reddit.com/r/coincashew/)

### :heart\_hands: Donations

* **Audience-funded guide**: If you found this helpful, [please consider supporting it directly.](/donations) :pray:
* **Support us on Gitcoin Grants:** We build this guide exclusively by community support!
* **Feedback or pull-requests**: <https://github.com/coincashew/coincashew>

## Last Words

> I stand upon the shoulders of giants and as such, invite you to stand upon mine. Use my work with or without attribution; I make no claim of "intellectual property." My ideas are the result of countless millenia of evolution - they belong to humanity.

<figure><img src="/files/uuUrHLVnTHEwjAQYS54Y" alt=""><figcaption><p>This is Leslie, the official mascot of Eth Staking</p></figcaption></figure>


# Monitoring your validator with Grafana and Prometheus

Prometheus is a monitoring platform that collects metrics from monitored targets by scraping metrics HTTP endpoints on these targets.

Grafana is a dashboard used to visualize the collected data.

[Official documentation is available here.](https://prometheus.io/docs/introduction/overview/) :book:

### 1. Install Prometheus and Node Exporter

```bash
sudo apt-get install -y prometheus prometheus-node-exporter
```

### 2. Install Grafana

```bash
sudo apt-get install -y apt-transport-https
sudo apt-get install -y software-properties-common wget
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
```

```bash
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt-get update && sudo apt-get install -y grafana
```

### 3. Enable services so they start automatically

```bash
sudo systemctl enable grafana-server prometheus prometheus-node-exporter
```

### 4. Create the **prometheus.yml** config file

Remove the default **prometheus.yml** configuration file and edit a new one.

```bash
sudo rm /etc/prometheus/prometheus.yml
sudo nano /etc/prometheus/prometheus.yml
```

Choose the tab for your consensus client. Paste the following configuration into the file.

{% tabs %}
{% tab title="Lighthouse" %}

```bash
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
   - job_name: 'node_exporter'
     static_configs:
       - targets: ['localhost:9100']
   - job_name: 'lighthouse'
     metrics_path: /metrics    
     static_configs:
       - targets: ['localhost:8008']
   - job_name: 'lighthouse_validator'
     metrics_path: /metrics
     static_configs:
       - targets: ['localhost:8009']
```

{% endtab %}

{% tab title="Nimbus" %}

```bash
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
   - job_name: 'node_exporter'
     static_configs:
       - targets: ['localhost:9100']
   - job_name: 'Nimbus'
     metrics_path: /metrics
     static_configs:
       - targets: ['localhost:8008']
   - job_name: 'Nimbus_Validator'
     metrics_path: /metrics
     static_configs:
       - targets: ['localhost:8009']
```

{% endtab %}

{% tab title="Teku" %}

```bash
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
   - job_name: 'node_exporter'
     static_configs:
       - targets: ['localhost:9100']
   - job_name: 'Teku'
     metrics_path: /metrics
     static_configs:
       - targets: ['localhost:8008']
   - job_name: 'Teku_Validator'
     metrics_path: /metrics
     static_configs:
       - targets: ['localhost:8009']
```

{% endtab %}

{% tab title="Prysm" %}

```bash
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
   - job_name: 'node_exporter'
     static_configs:
       - targets: ['localhost:9100']
   - job_name: 'validator'
     static_configs:
       - targets: ['localhost:8009']
   - job_name: 'Prysm'
     static_configs:
       - targets: ['localhost:8008']
```

{% endtab %}

{% tab title="Lodestar" %}

<pre class="language-bash"><code class="lang-bash"><strong>global:
</strong>  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
   - job_name: 'node_exporter'
     static_configs:
       - targets: ['localhost:9100']
   - job_name: 'beacon'
     metrics_path: /metrics    
     static_configs:
       - targets: ['localhost:8008']
   - job_name: 'validator'
     metrics_path: /metrics    
     static_configs:
       - targets: ['localhost:8009']
</code></pre>

{% endtab %}
{% endtabs %}

### 5. Setup prometheus for your execution client

Append the applicable job snippet for your execution client to the end of **prometheus.yml**.

{% hint style="warning" %}
**Spacing matters**. Ensure all `job_name` snippets are in alignment.
{% endhint %}

{% tabs %}
{% tab title="Geth" %}

```bash
   - job_name: 'geth'
     scrape_interval: 15s
     scrape_timeout: 10s
     metrics_path: /debug/metrics/prometheus
     scheme: http
     static_configs:
       - targets: ['localhost:6060']
```

{% endtab %}

{% tab title="Besu" %}

```bash
   - job_name: 'besu'
     scrape_interval: 15s
     scrape_timeout: 10s
     metrics_path: /metrics
     scheme: http
     static_configs:
     - targets:
       - localhost:6060
```

{% endtab %}

{% tab title="Nethermind" %}

```bash
   - job_name: 'nethermind'
     static_configs:
       - targets: ['localhost:6060']
```

{% endtab %}

{% tab title="Erigon" %}

```bash
   - job_name: 'erigon'
     scrape_interval: 10s
     scrape_timeout: 3s
     metrics_path: /debug/metrics/prometheus
     scheme: http
     static_configs:
       - targets: ['localhost:6060']
```

{% endtab %}

{% tab title="Reth" %}

```bash
   - job_name: 'reth'
     metrics_path: "/"
     scrape_interval: 10s
     static_configs:
       - targets: ['localhost:6060']
```

{% endtab %}
{% endtabs %}

Here's an example of a Lighthouse-Nethermind config:

```bash
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
   - job_name: 'node_exporter'
     static_configs:
       - targets: ['localhost:9100']
   - job_name: 'Lighthouse'
     metrics_path: /metrics
     static_configs:
       - targets: ['localhost:5054']
   - job_name: 'validators'
     metrics_path: /metrics
     static_configs:
       - targets: ['localhost:5064']
   - job_name: 'nethermind'
     static_configs:
       - targets: ['localhost:6060']
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Update file permissions.

```bash
sudo chmod 644 /etc/prometheus/prometheus.yml
```

Restart the services.

```bash
sudo systemctl restart grafana-server prometheus prometheus-node-exporter
```

Verify that the services are running.

```bash
sudo systemctl status grafana-server prometheus prometheus-node-exporter
```

### 6. Create a SSH Tunnel to Grafana

Each time you want to access Grafana, create a SSH tunnel with port 3000 forwarded.

{% tabs %}
{% tab title="Linux or MacOS" %}
Example of how to create a SSH tunnel in Linux or MacOS:

```bash
ssh -N -v <user>@<staking.node.ip.address> -L 3000:localhost:3000

#Full Example
ssh -N -v ethereum@192.168.1.69 -L 3000:localhost:3000
```

{% endtab %}

{% tab title="Windows" %}
Example of how to create a SSH tunnel in Windows with [Putty](https://putty.org/):

Navigate to Connection > SSH > Tunnels > Enter Source Port `3000` > Enter Destination `localhost:3000` > Click Add

![](/files/U5xlCUG5E0ti5LMCPYHq)

Now save your configuration. Navigate to Session > Enter a session name > Save

Click Open to open a connection
{% endtab %}
{% endtabs %}

Now you can access Grafana on your local machine by pointing a web browser to [http://localhost:3000](http://localhost:3000/)

### 7. Setup Grafana Dashboards

1. Open <http://localhost:3000>
2. Login with **admin** / **admin**
3. Change password
4. Click the **configuration gear** icon, then **Add data Source**
5. Select **Prometheus**
6. Set **Name** to **"Prometheus**"
7. Set **URL** to <http://localhost:9090>
8. Click **Save & Test**
9. **Download and save** your consensus client's json file. More json dashboard options available below. \[ [Lighthouse](https://raw.githubusercontent.com/Yoldark34/lighthouse-staking-dashboard/main/Yoldark_ETH_staking_dashboard.json) | [Teku ](https://grafana.com/api/dashboards/13457/revisions/2/download)| [Nimbus ](https://raw.githubusercontent.com/status-im/nimbus-eth2/master/grafana/beacon_nodes_Grafana_dashboard.json)| [Prysm ](https://raw.githubusercontent.com/GuillaumeMiralles/prysm-grafana-dashboard/master/less_10_validators.json)| [Prysm > 10 Validators](https://raw.githubusercontent.com/GuillaumeMiralles/prysm-grafana-dashboard/master/more_10_validators.json) | [Lodestar](https://raw.githubusercontent.com/ChainSafe/lodestar/unstable/dashboards/lodestar_summary.json) ]
10. **Download and save** your execution client's json file \[ [Geth](https://github.com/ethereum/go-ethereum/files/14211070/Geth-Cancun-Prometheus.json) | [Besu ](https://grafana.com/api/dashboards/10273/revisions/5/download)| [Nethermind](https://raw.githubusercontent.com/NethermindEth/metrics-infrastructure/master/grafana/provisioning/dashboards/nethermind.json) | [Erigon](https://raw.githubusercontent.com/ledgerwatch/erigon/devel/cmd/prometheus/dashboards/erigon.json) | [Reth](https://raw.githubusercontent.com/paradigmxyz/reth/main/etc/grafana/dashboards/overview.json) ]
11. **Download and save** a [node-exporter dashboard](https://grafana.com/api/dashboards/11074/revisions/9/download) for general system monitoring
12. Click **Create +** icon > **Import**
13. Add the consensus client dashboard via **Upload JSON file**
14. If needed, select Prometheus as **Data Source**.
15. Click the **Import** button.
16. Repeat steps 12-15 for the execution client dashboard.
17. Repeat steps 12-15 for the node-exporter dashboard.

{% hint style="warning" %}
:fire: **Troubleshooting common Grafana issues**

**Symptom 1**: Your dashboard is missing some data\_.\_

**Solution 1***:* Ensure that the execution or consensus client has enabled the appropriate metrics flag.

```bash
cat /etc/systemd/system/execution.service
cat /etc/systemd/system/consensus.service
```

* **Geth**: --http --metrics --pprof
* **Besu**: --metrics-enabled=true
* **Nethermind**: --Metrics.Enabled true
* **Erigon**: --metrics
* **Reth**: --metrics 127.0.0.1:9001
* **Lighthouse**: --validator-monitor-auto
* **Nimbus**: --metrics --metrics-port=8008
* **Teku**: --metrics-enabled=true --metrics-port=8008
* **Lodestar**: --metrics true

**Symptom 2**: Don't want to use SSH tunnels and you want to expose port 3000 to access Grafana, but understand the security concerns.

**Solution 2**: Open port 3000 in your ufw firewall. Access grafana at http\://\<node ipaddress>:3000

```
sudo ufw allow 3000
```

{% endhint %}

#### Example of Grafana Dashboards for each consensus client.

{% tabs %}
{% tab title="Lighthouse" %}
![Beacon Chain dashboard by sigp](/files/-MLQ7q9hFaNYwGho6sbP)

![Validator Client dashboard by sigp](/files/-MNWfnnhleNcCuhcxV9_)

Beacon Chain JSON Download link: <https://raw.githubusercontent.com/sigp/lighthouse-metrics/master/dashboards/Summary.json>

Validator Client JSON download link: <https://raw.githubusercontent.com/sigp/lighthouse-metrics/master/dashboards/ValidatorClient.json>

Credits: <https://github.com/sigp/lighthouse-metrics/>

![LH dashboard by Yoldark](/files/-MY1yXxlDMOj-SoqEJC7)

JSON Download link: <https://raw.githubusercontent.com/Yoldark34/lighthouse-staking-dashboard/main/Yoldark_ETH_staking_dashboard.json>

Credits: <https://github.com/Yoldark34/lighthouse-staking-dashboard>
{% endtab %}

{% tab title="Nimbus" %}
![Dashboard by status-im](/files/-MLaGFd6ZyPrECjDXjmm)

Credits: <https://github.com/status-im/nimbus-eth2/>

![Nimbus dashboard by metanull-operator](/files/-MY20PiRgnpI3ViITbSW)

JSON download link:

Credits: <https://github.com/metanull-operator/eth2-grafana/>
{% endtab %}

{% tab title="Teku" %}
![Teku by PegaSys Engineering](/files/-MMx4rhP3N0_7z0tES08)

Credits: <https://grafana.com/grafana/dashboards/13457>
{% endtab %}

{% tab title="Prysm" %}
![Prysm dashboard by GuillaumeMiralles](/files/-MLtCjxO392yO3NI4gFu)

Credits: <https://github.com/GuillaumeMiralles/prysm-grafana-dashboard>

![Prysm dashboard by metanull-operator](/files/-MY20PiRgnpI3ViITbSW)

JSON download link: <https://github.com/metanull-operator/eth2-grafana/raw/master/eth2-grafana-dashboard-single-source.json>

Credits: <https://github.com/metanull-operator/eth2-grafana/>
{% endtab %}

{% tab title="Lodestar" %}

<figure><img src="/files/3Qc23BO64NbBIhW5AT1m" alt=""><figcaption></figcaption></figure>

Credits: <https://raw.githubusercontent.com/ChainSafe/lodestar/unstable/dashboards/lodestar_summary.json>
{% endtab %}
{% endtabs %}

#### Example of Grafana Dashboards for each execution client.

{% tabs %}
{% tab title="Geth" %}
![Dashboard by karalabe](/files/-MNQ8xA4d1daR1qEezPP)

Credits: <https://gist.github.com/karalabe/e7ca79abdec54755ceae09c08bd090cd>

Blob enabled dashboard: <https://github.com/ethereum/go-ethereum/files/14211070/Geth-Cancun-Prometheus.json>
{% endtab %}

{% tab title="Besu" %}
![](/files/-MNQOM8AjwyS1As7jZPY)

Credits: <https://grafana.com/dashboards/10273>
{% endtab %}

{% tab title="Nethermind" %}
![](/files/-MNQOpWHG19DQ95eeIu8)

Credits: <https://github.com/NethermindEth/metrics-infrastructure>
{% endtab %}

{% tab title="Erigon" %}
![](/files/-McIG-6X8EFEA_Qadgy0)

Credits: <https://github.com/ledgerwatch/erigon/tree/devel/cmd/prometheus/dashboards>
{% endtab %}

{% tab title="Reth" %}

<figure><img src="/files/dxpp41NhiwHLaxO01BW7" alt=""><figcaption></figcaption></figure>

Credits: <https://github.com/paradigmxyz/reth/blob/main/etc/grafana/dashboards/overview.json>
{% endtab %}
{% endtabs %}

#### Example of Node-Exporter Dashboard

{% tabs %}
{% tab title="Node-Exporter Dashboard by starsliao" %}
**General system monitoring**

Includes: CPU, memory, disk IO, network, temperature and other monitoring metrics。

![](/files/-MP6vagYpr_OYSaYWy3b)

![](/files/-MP6vh9VT1UsWCJWanik)

Credits: [starsliao](https://grafana.com/grafana/dashboards/11074)
{% endtab %}
{% endtabs %}

### 8. Setup Alert Notifications

{% hint style="info" %}
Setup alerts to get notified if your validators go offline.
{% endhint %}

Get notified of problems with your validators. Choose between email, telegram, discord or slack.

<details>

<summary>Option 1: Email Notifications</summary>

1. Visit [https://beaconcha.in/](https://beaconcha.in)
2. Sign up for an account
3. Verify your **email**
4. Search for your **validator's public address**
5. Add validators to your watchlist by clicking the **bookmark symbol**.

</details>

<details>

<summary>Option 2: Telegram Notifications</summary>

1. On the menu of Grafana, select **Alerting.**
2. Click on **Contact points menu,** then **+Create contact point** butto&#x6E;**.**
3. Give the contact point a **name**.
4. Select **Telegram** from the Integration list.
5. To complete the **Telegram API settings**, a **Telegram channel** and \*\*bot \*\*are required. For instructions on setting up a bot with `@Botfather`, see [this section](https://core.telegram.org/bots#6-botfather) of the Telegram documentation. You need to create a BOT API token.
6. Create a new telegram group.
7. Invite the bot to your new group.
8. Type at least 1 message into the group to initialize it.
9. Visit [`https://api.telegram.org/botXXX:YYY/getUpdates`](https://api.telegram.org/botXXX:YYY/getUpdates) where `XXX:YYY` is your BOT API Token.
10. In the JSON response, find and copy the **Chat ID**. Find it between \*\*chat \*\*and **title**. *Example of Chat ID*: `-1123123123`

    ```
    "chat":{"id":-123123123,"title":
    ```
11. Paste the **Chat ID** into the corresponding field in **Grafana**.
12. **Save and test** the notification channel for your alerts.
13. Now you can create custom alerts from your dashboards. [Visit here to learn how to create alerts.](https://grafana.com/docs/grafana/latest/alerting/create-alerts/)

</details>

<details>

<summary>Option 3: Discord Notifications</summary>

1. On the menu of Grafana, select **Alerting.**
2. Click on **Contact points menu,** then **+Create contact point** butto&#x6E;**.**
3. Give the contact point a **name**.
4. Select **Discord** from the Integration list.
5. To complete the set up, a Discord server (and a text channel available) as well as a Webhook URL are required. For instructions on setting up a Discord's Webhooks, see [this section](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) of their documentation.
6. Enter the Webhook **URL** in the Discord notification settings panel.
7. Click **Send Test**, which will push a confirmation message to the Discord channel.
8. Now you can create custom alerts from your dashboards. [Visit here to learn how to create alerts.](https://grafana.com/docs/grafana/latest/alerting/create-alerts/)

</details>

<details>

<summary>Option 4: Slack Notifications</summary>

1. On the menu of Grafana, select **Alerting.**
2. Click on **Contact points menu,** then **+Create contact point** butto&#x6E;**.**
3. Give the contact point a **name**.
4. Select **Slack** from the Integration list.
5. For instructions on setting up a Slack's Incoming Webhooks, see [this section](https://api.slack.com/messaging/webhooks) of their documentation.
6. Enter the Slack Incoming Webhook URL in the **URL** field.
7. Click **Send Test**, which will push a confirmation message to the Slack channel.
8. Now you can create custom alerts from your dashboards. [Visit here to learn how to create alerts.](https://grafana.com/docs/grafana/latest/alerting/create-alerts/)

</details>


# Mobile App Node Monitoring by beaconcha.in

Learn how to monitor your validator & beacon node on the [beaconcha.in mobile app.](https://beaconcha.in/mobile)

Refer to the official guide found here: <https://kb.beaconcha.in/beaconcha.in-explorer/mobile-app-less-than-greater-than-beacon-node>

![beaconcha.in mobile app monitoring](/files/-McIHFLjf-2V_mF_8ZqL)


# Monitoring with Uptime Check by Google Cloud

{% hint style="info" %}
Who watches the watcher? With an external 3rd party tool like Uptime Check, you can have greater reassurance your validator is functioning in case of disasters such as power failure, hardware failure or internet outage. In these scenarios, the previously mentioned monitoring by Prometheus and Grafana would likely cease to function as well.

Credits to [Mohamed Mansour for inspiring this how-to guide](https://www.youtube.com/watch?v=txgOVDTemPQ).
{% endhint %}

Here's how to setup a no-cost monitoring service called Uptime Check by Google.

{% hint style="info" %}
For a video demo, watch [MohamedMansour's eth2 education videos](https://www.youtube.com/watch?v=txgOVDTemPQ). Please support his [GITCOIN grant](https://gitcoin.co/grants/1709/video-educational-grant). :pray:
{% endhint %}

1. Visit [cloud.google.com](https://cloud.google.com)
2. Search for **Monitoring** in the search field.
3. Click **Select a Project to Start Monitoring**.
4. Click **New Project.**
5. **Name your project and click Create.**
6. From the notifications menu, select your new project.
7. On the right column, there's a Monitoring Card. Click **Go to Monitoring**.
8. On the left menu, click **Uptime checks** and then **CREATE UPTIME CHECK.**
9. Type in a title i.e. ***Geth node***
10. Select protocol as ***TCP***
11. Enter your public IP address and port number. i.e. ip=**7.55.6.3** and port=**30303**
12. Select your desired frequency to check i.e. **5 minutes.**
13. Choose the region closest to you to check from. Click Next.
14. Create a Notification Channel. Click **Manage Notification Channels.**
15. Choose your desired settings. Pick from any or all of Slack, Webhook, Email or SMS.
16. Go back to Create Uptime Check window.
17. Within the notifications field, click the refresh button to load your new notification channels.
18. Select desired notifications.
19. Click **TEST** to verify your notifications are setup correctly.
20. Click **CREATE** to finish.


# PART II - MAINTENANCE


# Updating Execution Client

## :rocket: Automated Updates

:pill:**Install** [**EthPillar**](/coins/overview-eth/ethpillar): a simple companion UI for node management!&#x20;

Update your software with a keystroke.

To update, navigate to

`EthPillar > Execution Client > Update to latest release`

<figure><img src="/files/V3wTRIHTLu9ivOhCZLKC" alt=""><figcaption><p>EthPillar Update</p></figcaption></figure>

## :fast\_forward: Manual Updates

When a new release is cut, you will want to update to the latest stable release. The following shows you how to update your execution client.

{% hint style="warning" %}
Always review the **release notes** before updating. There may be changes requiring your attention.

* [Nethermind](https://github.com/NethermindEth/nethermind/releases)
* [Besu](https://github.com/hyperledger/besu/releases)
* [Geth](https://github.com/ethereum/go-ethereum/releases)
* [Erigon](https://github.com/ledgerwatch/erigon/releases)
  {% endhint %}

## Step 1: Select your execution client.

{% hint style="warning" %}
Staking setups prior to July 2023:\
Using **eth1** as the execution client service name? [V1 update instructions available here.](https://www.coincashew.com/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance/updating-your-execution-client)
{% endhint %}

{% hint style="info" %}
**Did you know you can use** [**EthPillar**](/coins/overview-eth/ethpillar)**?**<br>

:rocket: [**EthPillar**](/coins/overview-eth/ethpillar):  your node's buddy for easy and fast node management! Update your software with a keystroke.<br>

#### :arrow\_forward: EthPillar Quickstart: Ubuntu One-liner Install <a href="#quickstart-ubuntu-one-liner-install" id="quickstart-ubuntu-one-liner-install"></a>

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

{% endhint %}

### Nethermind

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-zip and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/NethermindEth/nethermind/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-x64)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O nethermind.zip $BINARIES_URL
unzip -o nethermind.zip -d $HOME/nethermind
rm nethermind.zip
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/nethermind
sudo mv $HOME/nethermind /usr/local/bin/nethermind
sudo systemctl start execution
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/nethermind
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
dotnet publish src/Nethermind/Nethermind.Runner -c release -o nethermind
```

Verify Nethermind was properly built by checking the version.

```shell
./nethermind/nethermind --version
```

Sample output of a compatible version.

```
Version: 1.25.2+78c7bf5f
Commit: 78c7bf5f2c0819f23e248ee6d108c17cd053ffd3
Build Date: 2024-01-23 06:34:53Z
OS: Linux x64
Runtime: .NET 8.0.1
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/nethermind
sudo mv $HOME/git/nethermind/nethermind /usr/local/bin
sudo systemctl start execution
```

</details>

### Besu

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/hyperledger/besu/releases/latest"
TAG=$(curl -s $RELEASE_URL | jq -r .tag_name)
BINARIES_URL="https://github.com/hyperledger/besu/releases/download/$TAG/besu-$TAG.tar.gz"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O besu.tar.gz $BINARIES_URL
tar -xzvf besu.tar.gz -C $HOME
rm besu.tar.gz
sudo mv $HOME/besu-${TAG} besu
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/besu
sudo mv $HOME/besu /usr/local/bin/besu
sudo systemctl start execution
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/besu
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
./gradlew installDist
```

Verify Besu was properly built by checking the version.

```shell
./build/install/besu/bin/besu --version
```

Sample output of a compatible version.

```
besu/v23.4.0/linux-x86_64/openjdk-java-17
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/besu
sudo cp -a $HOME/git/besu/build/install/besu /usr/local/bin/besu
sudo systemctl start execution
```

</details>

### Geth

<details>

<summary>Option 1 - Download binaries</summary>

<pre class="language-bash"><code class="lang-bash">RELEASE_URL="https://geth.ethereum.org/downloads"
<strong>FILE="https://gethstore.blob.core.windows.net/builds/geth-linux-amd64[a-zA-Z0-9./?=_%:-]*.tar.gz"
</strong>BINARIES_URL="$(curl -s $RELEASE_URL | grep -Eo $FILE | head -1)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O geth.tar.gz $BINARIES_URL
tar -xzvf geth.tar.gz -C $HOME --strip-components=1
</code></pre>

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Install new binaries, restart the services and cleanup files.

```bash
sudo mv $HOME/geth /usr/local/bin
sudo systemctl start execution
rm geth.tar.gz COPYING
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binary.

```bash
cd $HOME/git/go-ethereum
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
make geth
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/geth
sudo cp $HOME/git/go-ethereum/build/bin/geth /usr/local/bin
sudo systemctl start execution
```

</details>

### Erigon

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

<pre class="language-bash"><code class="lang-bash">RELEASE_URL="https://api.github.com/repos/erigontech/erigon/releases/latest"
<strong>BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux_amd64.tar.gz)"
</strong>
echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O erigon.tar.gz $BINARIES_URL
tar -xzvf erigon.tar.gz -C $HOME
mv erigon_* erigon
</code></pre>

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/erigon
sudo mv $HOME/erigon/erigon /usr/local/bin/erigon
sudo systemctl start execution
rm -rf erigon/ erigon.tar.gz
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binary.

```bash
cd $HOME/git/erigon
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
make erigon
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/erigon
sudo cp $HOME/git/erigon/build/bin/erigon /usr/local/bin
sudo systemctl start execution
```

</details>

### Reth

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/paradigmxyz/reth/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r '.assets[] | select(.name | startswith ("reth")) | .browser_download_url' | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O reth.tar.gz $BINARIES_URL
tar -xzvf reth.tar.gz -C $HOME
rm reth.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries, display the version, and restart the services.

```bash
sudo rm -rf /usr/local/bin/reth
sudo mv $HOME/reth /usr/local/bin
reth --version
sudo systemctl restart execution
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/reth
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build the release
cargo build --release
```

Verify Reth was built properly by checking the version number.

```bash
~/git/reth/target/release/reth --version
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
cargo build --release --features jemalloc
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/reth
sudo cp ~/git/reth/target/release/reth /usr/local/bin
sudo systemctl restart execution
```

</details>

## Step 2: Verify services and logs are working properly

```bash
# Verify services status
sudo systemctl status execution
```

```bash
# Check logs
sudo journalctl -fu execution
```

## Step 3: Optional - Verify your validator's attestations on public block explorer

1\) Visit [https://beaconcha.in/](https://beaconcha.in) or [https://beaconscan.com/](https://beaconscan.com)

2\) Enter your validator's pubkey into the search bar and look for successful attestations.


# Updating Consensus Client

Scenario: In discord, you see an alert that your consensus client just announced a new release. How best to update?

## :rocket: Automated Updates

:pill:**Install** [**EthPillar**](/coins/overview-eth/ethpillar): a simple companion UI for node management!&#x20;

Update your software with a keystroke.

To update, navigate to

`EthPillar > Consensus Client > Update to latest release`

<figure><img src="/files/NVpfKft5gehiXZ5eznlx" alt=""><figcaption><p>EthPillar Update</p></figcaption></figure>

## :fast\_forward: Manual Updates

When a new release is cut, you will want to update to the latest stable release. The following shows you how to update your beacon chain and validator.

{% hint style="warning" %}
Always review the **release notes** before updating. There may be changes requiring your attention.

* [Lighthouse](https://github.com/sigp/lighthouse/releases)
* [Lodestar](https://github.com/ChainSafe/lodestar/releases)
* [Teku](https://github.com/ConsenSys/teku/releases)
* [Nimbus](https://github.com/status-im/nimbus-eth2/releases)
* [Prysm](https://github.com/prysmaticlabs/prysm/releases)
  {% endhint %}

## Step 1: Select your consensus client.

{% hint style="warning" %}
Staking setups prior to July 2023:

Using **beacon-chain** as the consensus client service name? [V1 update instructions available here.](https://www.coincashew.com/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance/updating-your-consensus-client)
{% endhint %}

{% hint style="info" %}
**Did you know you can use** [**EthPillar**](/coins/overview-eth/ethpillar)**?**<br>

:rocket: [**EthPillar**](/coins/overview-eth/ethpillar):  your node's buddy for easy and fast node management! Update your software with a keystroke.<br>

#### :arrow\_forward: EthPillar Quickstart: Ubuntu One-liner Install <a href="#quickstart-ubuntu-one-liner-install" id="quickstart-ubuntu-one-liner-install"></a>

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

{% endhint %}

### Lighthouse

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/sigp/lighthouse/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lighthouse.tar.gz $BINARIES_URL
# Untar
tar -xzvf lighthouse.tar.gz -C $HOME
# Cleanup
rm lighthouse.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

<pre class="language-bash"><code class="lang-bash">sudo rm /usr/local/bin/lighthouse
<strong>sudo mv $HOME/lighthouse /usr/local/bin/lighthouse
</strong><strong>sudo systemctl start consensus validator
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/lighthouse
git fetch --all && git checkout stable && git pull
make
```

:bulb:**Tip**: Improve some Lighthouse benchmarks by around 20% at the expense of increased compile time? Use `maxperf` profile.

* To compile with maxperf, replace the above `make` command with

```bash
PROFILE=maxperf make
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
make
```

Verify lighthouse was built properly by checking the version number.

```
lighthouse --version
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo rm /usr/local/bin/lighthouse
</strong><strong>sudo cp $HOME/.cargo/bin/lighthouse /usr/local/bin/lighthouse
</strong>sudo systemctl start consensus validator
</code></pre>

</details>

### Lodestar

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ChainSafe/lodestar/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://github.com/ChainSafe/lodestar/releases/download/${LATEST_TAG}/lodestar-${LATEST_TAG}-linux-amd64.tar.gz"
	
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lodestar.tar.gz $BINARIES_URL
# Untar
tar -xzvf lodestar.tar.gz -C $HOME
# Cleanup
rm lodestar.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/lodestar && sudo mkdir -p /usr/local/bin/lodestar
sudo mv $HOME/lodestar /usr/local/bin/lodestar
sudo systemctl start consensus validator
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Pull the latest source and build Lodestar.

```bash
cd ~/git/lodestar
git checkout stable && git pull
yarn install
yarn run build
```

:warning: In case of build errors or missing dependencies, run the following command.

```bash
yarn clean:nm && yarn install
```

Verify Lodestar was installed properly by displaying the version.

```bash
./lodestar --version
```

Sample output of a compatible version.

```
🌟 Lodestar: TypeScript Implementation of the Ethereum Consensus Beacon Chain.
  * Version: v1.8.0/stable/a4b29cf
  * by ChainSafe Systems, 2018-2022
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/lodestar
sudo cp -a $HOME/git/lodestar /usr/local/bin/lodestar
sudo systemctl start consensus validator
```

</details>

### Teku

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ConsenSys/teku/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://artifacts.consensys.net/public/teku/raw/names/teku.tar.gz/versions/${LATEST_TAG}/teku-${LATEST_TAG}.tar.gz"
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O teku.tar.gz $BINARIES_URL
# Untar
tar -xzvf teku.tar.gz -C $HOME
# Rename folder
mv teku-${LATEST_TAG} teku
# Cleanup
rm teku.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus
</strong><strong>
</strong><strong># If running Standalone Teku Validator
</strong><strong>sudo systemctl stop validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/teku
sudo mv $HOME/teku /usr/local/bin/teku
sudo systemctl start consensus

# If running Standalone Teku Validator
sudo systemctl start validator
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Fetch the latest tags and build the binaries.

```bash
cd ~/git/teku
# Get new tags
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/ConsenSys/teku/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
./gradlew distTar installDist
```

Verify Teku was built properly by displaying the version.

```shell
cd $HOME/git/teku/build/install/teku/bin
./teku --version
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus
</strong><strong>
</strong># If running Standalone Teku Validator
sudo systemctl stop validator
</code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/teku
sudo cp -a $HOME/git/teku/build/install/teku /usr/local/bin/teku
sudo systemctl start consensus

# If running Standalone Teku Validator
sudo systemctl start validator
```

</details>

### Nimbus

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/status-im/nimbus-eth2/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep _Linux_amd64.*.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O nimbus.tar.gz $BINARIES_URL
# Untar
tar -xzvf nimbus.tar.gz -C $HOME
# Rename folder
mv nimbus-eth2_Linux_amd64_* nimbus
# Cleanup
rm nimbus.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus
</strong><strong># If running standalone Nimbus Validator
</strong><strong>sudo systemctl stop validator
</strong></code></pre>

Remove old binaries, install new binaries, cleanup and restart the services.

```bash
sudo rm /usr/local/bin/nimbus_beacon_node
sudo rm /usr/local/bin/nimbus_validator_client
sudo mv nimbus/build/nimbus_beacon_node /usr/local/bin
sudo mv nimbus/build/nimbus_validator_client /usr/local/bin
rm -r nimbus
sudo systemctl start consensus
# If running standalone Nimbus Validator
sudo systemctl start validator
```

Reminder: In combined CL+VC Nimbus configuration, there will be no validator systemctl service.

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Pull the latest source code and build the binary.

<pre class="language-bash"><code class="lang-bash">cd ~/git/nimbus-eth2
git checkout stable &#x26;&#x26; git pull
make -j$(nproc) update
<strong>make -j$(nproc) nimbus_beacon_node
</strong>make -j$(nproc) nimbus_validator_client
</code></pre>

Verify Nimbus was built properly by displaying the version.

```bash
cd $HOME/git/nimbus-eth2/build
./nimbus_beacon_node --version
```

Stop the services.

```bash
sudo systemctl stop consensus
# If running standalone Nimbus Validator
sudo systemctl stop validator
```

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm /usr/local/bin/nimbus_beacon_node
sudo rm /usr/local/bin/nimbus_validator_client
sudo cp $HOME/git/nimbus-eth2/build/nimbus_beacon_node /usr/local/bin
sudo cp $HOME/git/nimbus-eth2/build/nimbus_validator_client /usr/local/bin
sudo systemctl start consensus
# If running standalone Nimbus Validator
sudo systemctl start validator
```

Reminder: In combined CL+VC Nimbus configuration, there will be no validator systemctl service.

</details>

### Prysm

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest binaries.

```bash
cd $HOME
prysm_version=$(curl -f -s https://prysmaticlabs.com/releases/latest)
file_beacon=beacon-chain-${prysm_version}-linux-amd64
file_validator=validator-${prysm_version}-linux-amd64
curl -f -L "https://prysmaticlabs.com/releases/${file_beacon}" -o beacon-chain
curl -f -L "https://prysmaticlabs.com/releases/${file_validator}" -o validator
chmod +x beacon-chain validator
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm /usr/local/bin/beacon-chain
sudo rm /usr/local/bin/validator
sudo mv beacon-chain validator /usr/local/bin
sudo systemctl start consensus validator
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Pull the latest source code and build the binaries.

```bash
cd $HOME/git/prysm
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/OffchainLabs/prysm/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
go build -o=./build/beacon-chain ./cmd/beacon-chain
go build -o=./build/validator ./cmd/validator
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm /usr/local/bin/beacon-chain
sudo rm /usr/local/bin/validator
sudo cp $HOME/git/prysm/build/beacon-chain /usr/local/bin
sudo cp $HOME/git/prysm/build/validator /usr/local/bin
sudo systemctl start consensus validator
```

</details>

## Step 2: Verify services and logs are working properly

{% tabs %}
{% tab title="Lighthouse | Prysm | Lodestar | Nimbus | Teku" %}

```bash
# Verify services status
sudo systemctl status consensus validator
```

```bash
# Check logs
sudo journalctl -fu consensus
```

```bash
sudo journalctl -fu validator
```

{% endtab %}

{% tab title=" Combined BN+VC for Nimbus | Teku" %}

```bash
# Check services status
sudo systemctl status consensus 
```

```bash
# Check logs
sudo journalctl -fu consensus
```

{% endtab %}
{% endtabs %}

## Step 3: Optional - Verify your validator's attestations on public block explorer

1\) Visit [https://beaconcha.in/](https://beaconcha.in) or [https://beaconscan.com/](https://beaconscan.com)

2\) Enter your validator's pubkey into the search bar and look for successful attestations.


# Backups Checklist: Critical Staking Node Data

{% hint style="info" %}
Annually, it's good practice to review and refamilarize yourself that your staking data is backed up and accessible.
{% endhint %}

{% hint style="danger" %}
:fire: **Critical Crypto Reminder:** **Keep your mnemonics, keep your ETH.**

* **Withdrawal Wallet Seed Phrase**: Ideally this is secured by a hardware wallet. Most important piece of data and represents your ETH!
* **Validator Key Mnemonic**: Write this down **offline**. Not email. Not cloud.
* **Validator\_keys directory**: Contains keystore files and deposit\_data.
* **Password for keystore files:** Required when installing validators.

**Suggestions**:

* Create multiple copies. *Best stored in a* [*metal seed.*](https://jlopp.github.io/metal-bitcoin-storage-reviews/)
* Make **offline backups**, such as to a USB key, of your **`validator_keys`** directory.
  {% endhint %}


# Uninstalling Staking Node

{% hint style="info" %}
Whether changing clients for client diversity purposes, moving to a new node, or retiring a staking node, here's how to uninstall the three key components of a staking node.
{% endhint %}

### Uninstalling execution client&#x20;

```bash
sudo systemctl stop execution
sudo systemctl disable execution
sudo rm /etc/systemd/system/execution.service

#Nethermind
sudo rm -rf /usr/local/bin/nethermind
sudo rm -rf /var/lib/nethermind

#Besu
sudo rm -rf /usr/local/bin/besu
sudo rm -rf /var/lib/besu

#Geth
sudo rm -rf /usr/local/bin/geth
sudo rm -rf /var/lib/geth

#Erigon
sudo rm -rf /usr/local/bin/erigon
sudo rm -rf /var/lib/erigon

#Reth
sudo rm -rf /usr/local/bin/reth
sudo rm -rf /var/lib/reth

sudo userdel execution
```

### Uninstalling consensus client&#x20;

```bash
sudo systemctl stop consensus
sudo systemctl disable consensus
sudo rm /etc/systemd/system/consensus.service

#Lighthouse
sudo rm -rf /usr/local/bin/lighthouse
sudo rm -rf /var/lib/lighthouse

#Lodestar
sudo rm -rf /usr/local/bin/lodestar
sudo rm -rf /var/lib/lodestar

#Teku
sudo rm -rf /usr/local/bin/teku
sudo rm -rf /var/lib/teku

#Nimbus
sudo rm -rf /usr/local/bin/nimbus_beacon_node
sudo rm -rf /var/lib/nimbus

#Prysm
sudo rm -rf /usr/local/bin/beacon-chain
sudo rm -rf /var/lib/prysm

sudo userdel consensus
```

### Uninstalling validator

```bash
sudo systemctl stop validator
sudo systemctl disable validator
sudo rm /etc/systemd/system/validator.service

#Lighthouse
sudo rm -rf /var/lib/lighthouse/validators

#Lodestar
sudo rm -rf /var/lib/lodestar/validators

#Teku, if running Standalone Teku Validator
sudo rm -rf /var/lib/teku_validator

#Nimbus, if running standalone Nimbus Validator
sudo rm -rf /var/lib/nimbus_validator
sudo rm -rf /usr/local/bin/nimbus_validator_client

#Prysm
sudo rm -rf /usr/local/bin/validator
sudo rm -rf /var/lib/prysm/validators

sudo userdel validator
```


# Finding the longest attestation slot gap

Find the best slot gap to avoid missing any validator duties.

## :fast\_forward: Quick steps guide

{% hint style="info" %}
The following steps align with our [mainnet guide](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet). You may need to adjust file names and directory locations where appropriate. The core concepts remain the same.
{% endhint %}

### :dagger: Why do I want to calculate the longest attestation slot gap?

* Your validators are assigned duties to attest and propose blocks.
* Understanding the schedule of your validator's duties better, you can find the best time to plan consensus/execution client updates, system reboots or outages.
* Since the Altair Hard Fork, checking sync committee membership is a must before performing any maintenance. This will give you up to [\~27 hours of advanced notice](https://github.com/ethereum/consensus-specs/pull/2453) in case your validators have been selected for sync committee duties.

### :robot: Pre-requisites

* python3
* validator index number(s) -- Lookup on [https://beaconcha.in/](https://beaconcha.in) or [https://beaconscan.com/](https://beaconscan.com)
* Works with **Lighthouse / Teku / Prysm** currently

{% hint style="success" %}
:sparkles: Kudos to **pietjepuk2** on Discord for authoring this process.
{% endhint %}

### :construction: How to Run the Validator Duties script

1\. Install python3

```
sudo apt update && sudo apt-get install python3
```

2\. Download [pietjepuk2](https://gist.github.com/pietjepuk2)'s `get_validator_duties.py` python script.

{% tabs %}
{% tab title="Lighthouse | Teku" %}

```bash
cd $HOME
wget https://gist.githubusercontent.com/pietjepuk2/eb021db978ad20bfd94dce485be63150/raw/cc874b3035f97495416353f203d70477b31ab05d/get_validator_duties.py
```

{% endtab %}

{% tab title="Prysm" %}

```bash
cd $HOME
# modified by mohamedmansour for prysm
wget https://gist.githubusercontent.com/mohamedmansour/9a82071802ffd58bef7ab5db530f23fd/raw/d48a3f0948cf2ae8cf571b42d50f80d66841118f/get_validator_duties.py
```

{% endtab %}
{% endtabs %}

3\. Enter your validator index numbers as parameters to the python script.

```bash
python3 get_validator_duties.py <validator index number(s)>
# Example
# python3 get_validator_duties.py 1000 1001 1002 1003
```

Sample Output showing the longest gap in seconds, # of slots and time range.

> Longest gap (first):
>
> 120.0 seconds (10 slots), from 13:37:35 until 13:39:35

{% hint style="info" %}
:question:**Troubleshooting:**

* The python script calls the `http API` on port 5052.
* Ensure the `http API` is enabled for your consensus layer client.
  * teku: `--rest-api-enabled=true`
* Teku by default uses port 5051, rather than 5052. Search and replace the port number before using.
  {% endhint %}

{% hint style="warning" %}
:fire: **Script Usage Caveats**:

* This version does not include block proposals, although the odds of having one scheduled are really low of course.
* Block proposal duties are only known for the current epoch, whereas attestation duties are known for the current and next one.
  {% endhint %}

{% hint style="success" %}
Nice work. Now you now the best gap to avoid missing any validator duties.
{% endhint %}

## :robot: Start staking by building a validator <a href="#start-staking-by-building-a-validator" id="start-staking-by-building-a-validator"></a>

### Visit here for our [Mainnet guide](https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet)

{% hint style="success" %}
Congrats on completing the guide. ✨

Did you find our guide useful? Send us a signal with a tip and we'll keep updating it.

It really energizes us to keep creating the best crypto guides.

Use [cointr.ee to find our donation](https://cointr.ee/coincashew) addresses. 🙏

Any feedback and all pull requests much appreciated. 🌛
{% endhint %}

## :jigsaw: Reference Material

{% embed url="<https://gist.githubusercontent.com/pietjepuk2/eb021db978ad20bfd94dce485be63150/raw/cc874b3035f97495416353f203d70477b31ab05d/get_validator_duties.py>" %}

<https://gist.github.com/mohamedmansour/9a82071802ffd58bef7ab5db530f23fd>


# Checking my eth validator's sync committee duties

Avoid missing extra ETH income and get rewarded for 24hours of sync committee duties.

## :fast\_forward: Quick steps guide

{% hint style="info" %}
The following steps align with our [mainnet guide](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet). You may need to adjust file names and directory locations where appropriate. The core concepts remain the same.
{% endhint %}

### :dagger: Why do I want to check my sync committee duties ?

* Since the Altair Hard Fork, checking sync committee membership is a must before performing any maintenance. This will give you up to [\~27 hours of advanced notice](https://github.com/ethereum/consensus-specs/pull/2453) in case your validators have been selected for sync committee duties.
* Understanding the schedule of your validator's duties better, you can find the best time to plan consensus/execution client updates, system reboots or outages.

### :robot: Pre-requisites

* Linux bash shell or command line
* Assumes you will be running this script on the beacon node. If running remotely, you might need to change your beacon node's http API to bind from localhost to 0.0.0.0
* Your ETH validator index number(s) -- Enter your validator's public key on [https://beaconcha.in/](https://beaconcha.in) or [https://beaconscan.com/](https://beaconscan.com) Example of Validator index # 12345 is shown below.

<figure><img src="/files/cNzZQvp0q9elSSyDc7st" alt=""><figcaption><p>Given your validator's public key, the index number is shown. Example of Validator 12345 from <a href="https://beaconcha.in/validator/12345">https://beaconcha.in/validator/12345</a></p></figcaption></figure>

{% hint style="success" %}
:sparkles: Kudos to [**2038**](https://www.reddit.com/user/2038/) on Reddit for [authoring this process.](https://www.reddit.com/r/ethstaker/comments/qjlfsf/how_to_check_upcoming_sync_committee_membership/)
{% endhint %}

### :construction: How to Check Sync Committee Duties script

1\. Create a `check_sync_committee.sh` script with a text editor, nano.

```
nano check_sync_committee.sh
```

2\. Paste the following script content and then save your file. CTRL+O, enter, then CTRL+X.

```
#!/bin/sh

BEACON_NODE="http://localhost:5052"
VALIDATOR_LIST=$(echo "$@" | tr ' ' '|')

epoch_to_time(){
    expr 1606824000 + \( $1 \* 384 \)
    }

time_to_epoch(){
    expr \( $1 - 1606824000 \) / 384
    }

get_committee(){
    URLSTEM="${BEACON_NODE}/eth/v1/beacon/states/finalized"
    curl -X GET "${URLSTEM}/sync_committees?epoch=$1" 2> /dev/null \
    | sed -e 's/["]/''/g' | cut -d'[' -f2 | cut -d']' -f1 | tr ',' '\n'
    }

search_committee(){
    get_committee $2 | grep -Ex $VALIDATOR_LIST \
    | awk -v c=$1 '{print "validator:", $1, "found in", c, "sync committee"}'
    }

display_epoch(){
    echo "epoch: $1 : $(date -d@$(epoch_to_time $1)) <-- $2"
    }

CURR_EPOCH=$(time_to_epoch $(date +%s))
CURR_START_EPOCH=`expr \( $CURR_EPOCH / 256 \) \* 256`
NEXT_START_EPOCH=`expr $CURR_START_EPOCH + 256`
NEXTB1_START_EPOCH=`expr $NEXT_START_EPOCH + 256`

echo
display_epoch $CURR_START_EPOCH   "current sync committee start"
display_epoch $CURR_EPOCH         "now"
display_epoch $NEXT_START_EPOCH   "next sync committee start"
display_epoch $NEXTB1_START_EPOCH "next-but-one sync committee start"
echo

if [ "$#" -gt 0 ]
then
    search_committee "current" $CURR_EPOCH
    search_committee "next"    $NEXT_START_EPOCH
fi
```

3\. Add execute permissions to the script.

```
 chmod +x check_sync_committee.sh
```

4\. Enter your validator index numbers as parameters to the script.

```bash
./check_sync_committee.sh <validator index number(s)>
# Example
# ./check_sync_committee.sh 1000 1001 1002 1003
```

Sample Output of the script:

> ```
> ./check_sync_committee.sh 123511 124216 
>
> epoch: 75008 : Sat 30 Oct 21:51:12 BST 2021 <-- current sync committee start
> epoch: 75115 : Sun 31 Oct 08:16:00 GMT 2021 <-- now
> epoch: 75264 : Mon  1 Nov 00:09:36 GMT 2021 <-- next sync committee start
> epoch: 75520 : Tue  2 Nov 03:28:00 GMT 2021 <-- next-but-one sync committee start
>
> validator: 123511 found in current sync committee
> validator: 124216 found in next sync committee
> ```

This output indicates the following:

* it is currently epoch 75115
* and validator #123511 is in current sync committee from epoch 75008 to epoch 75263
* and validator #124216 is in next sync committee from epoch 75264 to epoch 75520

If there is no output, then no validators are scheduled for current or next sync committee.

{% hint style="info" %}
:question:**Troubleshooting:**

* The python script calls the `http API`
* Ensure the `http API` is enabled for your consensus layer client.
  * teku: `--rest-api-enabled=true`
* Teku by default uses port 5051, rather than 5052. Replace the port number before using.
  * example: BEACON\_NODE="<http://localhost:5051>"
    {% endhint %}

{% hint style="warning" %}
:fire: **Script Usage Caveats**:

* Sync committee duties are only known for the current AND next sync committee period.
  {% endhint %}


# Checklist | Confirming a healthy functional ETH staking node

Scenario: How do I figure out and confirm that everything is working properly (execution client in sync, consensus client in sync, etc.)

## :fast\_forward: Quick steps guide

{% hint style="info" %}
The following steps align with our [mainnet guide](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet). You may need to adjust file names and directory locations where appropriate. The core concepts remain the same.
{% endhint %}

### :rocket: Execution client Checklist

| Concern                                       | Solution                                                                                                                                                                                                                                                                                          |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Execution client in sync                      | <p>Ensure your node's block number matches the tip block of a <a href="http://etherscan.io">public block explorer</a>. Find your execution client block # with command <code>journalctl -fu execution</code></p><p><strong><code>Example log output:</code></strong><code>INFO \[12-06</code></p> |
| Ports open                                    | <p>Confirm ports are reachable with an external port checker such as</p><p><a href="https://www.yougetsignal.com/tools/open-ports/"><https://www.yougetsignal.com/tools/open-ports/></a></p>                                                                                                      |
| Check execution client logs for errors        | Use the command `journalctl -fu eth1`                                                                                                                                                                                                                                                             |
| Understand how to stop/start Execution client | <p><code>sudo systemctl stop execution</code></p><p><code>sudo systemctl start execution</code></p>                                                                                                                                                                                               |
| Understand how to update my Execution client  | Refer to [this quick guide](/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-testnet-prater-1/maintenance/updating-execution-client).                                                                                                                                |
| Reduce bandwidth usage                        | Refer to [the mainnet guide.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/reducing-network-bandwidth-usage)                                                                                                                                               |
| Execution client node redundancy              | Refer to [the mainnet guide.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/improving-validator-attestation-effectiveness#strategy-2-eth1-redundancy)                                                                                                       |

### :dna: Consensus client Checklist

| Concern                                               | Solution                                                                                                                                                                                                                                                                                                                                                                                       |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Installed latest stable release                       | Refer to [how to update consensus client.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance/updating-consensus-client)                                                                                                                                                                                                                                |
| Beacon chain client can connect to Execution client   | <p>Check for a response with the command:<code>curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"web3\_clientVersion","params":\[],"id":67}' <http://localhost:8545></code></p><p>You should receive a response similar to:</p><p><code>{"jsonrpc":"2.0","id":67,"result":"Geth/v1.9.24-stable-cc05b050/linux-amd64/go1.15.5"}</code></p>                    |
| Beacon chain is sync'd to mainnet                     | Ensure your block number matches the slot# of a [public block explorer](https://beaconcha.in). Find your consensus client's beacon chain slot # with in logs with command `journalctl -fu beacon-chain`                                                                                                                                                                                        |
| Check consensus client's beacon chain logs for errors | Use the command `journalctl -fu consensus`                                                                                                                                                                                                                                                                                                                                                     |
| Ports open                                            | <p>Confirm ports are reachable with an external port checker such as</p><p><a href="https://www.yougetsignal.com/tools/open-ports/"><https://www.yougetsignal.com/tools/open-ports/></a> or <a href="https://canyouseeme.org"><https://canyouseeme.org/></a> .</p><p><a href="/pages/Tb57gqyH5WWgWgjhdeME#bricks-mandatory-configure-your-firewall">Click here for Port # information</a>.</p> |
| Understand how to stop/start consensus client         | <p><code>sudo systemctl stop consensus</code></p><p><code>sudo systemctl start consensus</code></p>                                                                                                                                                                                                                                                                                            |
| Understand how to update my consensus client          | Refer to this quick guide.                                                                                                                                                                                                                                                                                                                                                                     |
| Join Discord                                          | Refer to [the mainnet guide](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/joining-the-community-on-discord-and-reddit)                                                                                                                                                                                                                                                |

### :key2: Consensus Validator Client Checklist

| Concern                                      | Solution                                                                                                                                                                                           |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Verify keystores are properly imported       | Refer to the mainnet guide's section on importing keys.                                                                                                                                            |
| Check validator logs for errors              | Use the command `journalctl -fu validator`                                                                                                                                                         |
| Verify attestations are working              | Check your validators pubkey against a [public block explorer.](https://beaconscan.com)                                                                                                            |
| Verified my mnemonic phrase can be restored. | Refer to [the mainnet guide.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/verifying-your-mnemonic-phrase)                                                  |
| Understand how to add more validators        | Refer to this [quick guide.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/adding-a-new-validator-to-an-existing-setup)                                      |
| Know how to stop/start validator             | <p><code>sudo systemctl stop validator</code></p><p><code>sudo systemctl start validator</code></p>                                                                                                |
| Beacon-node redundancy                       | Refer to [the mainnet guide.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/improving-validator-attestation-effectiveness#strategy-4-beacon-node-redundancy) |

### :bricks: Validator Node Security Checklist

| Concern                                          | Solution                                       |
| ------------------------------------------------ | ---------------------------------------------- |
| Secure the root account                          | Refer to the best security practices document. |
| Connect with SSH Keys Only                       | Refer to the best security practices document. |
| Harden SSH on a random port                      | Refer to the best security practices document. |
| Setup 2-FA for SSH (Optional)                    | Refer to the best security practices document. |
| Secure the Shared Memory                         | Refer to the best security practices document. |
| Setup a firewall                                 | Refer to the best security practices document. |
| Setup port forwarding on my router               | Refer to the best security practices document. |
| Setup intrusion-prevention monitoring            | Refer to the best security practices document. |
| Whitelisted my local machine in the ufw firewall | Refer to the best security practices document. |
| Whitelisted my local machine in Fail2ban         | Refer to the best security practices document. |
| Verify the listening ports                       | Refer to the best security practices document. |

### :vertical\_traffic\_light: Validator Node Maintenance and Best Practices Checklist

| Concern                                                  | Solution                                                                                                                                                                                                                                                                    |
| -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Enabled automatic OS patching                            | Refer to the best security practices document.                                                                                                                                                                                                                              |
| Setup chrony or other NTP time sync service              | Refer to the mainnet guide.                                                                                                                                                                                                                                                 |
| Setup Prometheus and Grafana Monitoring/Alerts/Dashboard | Refer to the mainnet guide.                                                                                                                                                                                                                                                 |
| Understand how to handle a power outage                  | In case of power outage, you want your validator machine to restart as soon as power is available. In the BIOS settings, change the **Restore on AC / Power Loss** or **After Power Loss** setting to always on. Better yet, install an Uninterruptable Power Supply (UPS). |
| Understand how to migrate consensus clients              | Refer to the mainnet guide.                                                                                                                                                                                                                                                 |
| Understand how to voluntary exit                         | Refer to the mainnet guide.                                                                                                                                                                                                                                                 |
| Used all available LVM disk space                        | Refer to the mainnet guide.                                                                                                                                                                                                                                                 |
| Understand important directory locations                 | Refer to the mainnet guide.                                                                                                                                                                                                                                                 |


# PART III - TIPS


# Voluntary Exiting a Validator

Remove a validator from staking duties.

## :track\_next: Voluntary Exit Timeline Visualized

<figure><img src="/files/fxvv1JwYri1z6XLUy4ji" alt=""><figcaption><p>Voluntary exit procedures involve multiple steps and potential delays. For a complete overview of these steps and delays, refer to Ladislaus's informative graphic.</p></figcaption></figure>

## :clap: Purpose

Use the Voluntary Exit command to signal your intentions to permanently stop your duties as a validator.

* **Timeline**: Voluntary exiting is possible after your validator is actively validating. If there is no exit queue, the exit process requires at least 4 epochs, or 26 minutes. After your validator is "exited", and proceeds through the "withdrawal delay" phase and "withdrawal processing" phase, your ETH is automatically swept back to your withdrawal address.
* **Consequences**: Once a validator is in exited state, it's non-reversible. You would need to re-key, or generate new validator keys to start staking again.
* **ETH Deposit**: In order to re-claim your 32ETH validator deposit and perform a full withdrawal, you must have previously set a Withdrawal Address. If not yet set, see here: [0x01 withdrawal address.](/coins/overview-eth/update-withdrawal-keys-for-ethereum-validator-bls-to-execution-change-or-0x00-to-0x01-with-ethdo)
* **Responsibilities**: After your validator leaves the exit queue and is truly exited, it is safe to turn off your execution client, consensus client and validator.

Reference: <https://liquidcollective.io/eth-activations-and-exits/>

## :computer: How-to initiate a voluntary exit

{% tabs %}
{% tab title="Lighthouse" %}

```bash
sudo lighthouse account validator exit \
--keystore /var/lib/lighthouse/validators/<0x validator>/<keystore.json file> \
--beacon-node http://localhost:5052 \
--network mainnet
```

Example:

```bash
sudo lighthouse account validator exit \
--keystore /var/lib/lighthouse/validators/0x838f024753064e90fd8fa183400af82dd2103df885/keystore-m_12311_12-112312.json \
--beacon-node http://localhost:5052 \
--network mainnet
```

{% endtab %}

{% tab title="Teku" %}

```bash
sudo /usr/local/bin/teku/bin/teku voluntary-exit \
--beacon-node-api-endpoint=http://127.0.0.1:5052 \
--validator-keys=<path to keystore.json>:<path to password.txt file>
```

Example:

```
sudo /usr/local/bin/teku/bin/teku voluntary-exit \
--beacon-node-api-endpoint=http://127.0.0.1:5052 \
--validator-keys=/var/lib/teku/validator_keys/keys/validator_1abc3.json:/etc/teku/validators-password.txt
```

{% endtab %}

{% tab title="Nimbus" %}

```bash
sudo /usr/local/bin/nimbus_beacon_node deposits exit \
--validator=<VALIDATOR_PUBLIC_KEY> \
--data-dir=/var/lib/nimbus
```

Example:

```bash
sudo /usr/local/bin/nimbus_beacon_node deposits exit \
--validator=0x838f0247538237064e90fd8fa183400af82dd2103df885 \
--data-dir=/var/lib/nimbus
```

{% endtab %}

{% tab title="Prysm" %}

```bash
sudo /usr/local/bin/validator accounts voluntary-exit \
--wallet-dir=/var/lib/prysm/validators
```

{% endtab %}

{% tab title="Lodestar" %}
Stop Lodestar validator

```bash
sudo systemctl stop validator
```

Run the voluntary exit command

<pre class="language-bash"><code class="lang-bash"><strong># change directories to binary folder
</strong>cd /usr/local/bin/lodestar
<strong>
</strong># the voluntary exit command
sudo ./lodestar validator voluntary-exit
</code></pre>

Restart validator

```bash
sudo systemctl restart validator
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Troubleshooting**: To perform a voluntary exit, make sure your consensus client (aka beacon node) is running with **REST-API** enabled.
{% endhint %}

### Official reference documentation from each team can be found below:

* [Exiting a Teku validator](https://docs.teku.consensys.net/how-to/voluntarily-exit)
* [Exiting a Prysm validator](https://docs.prylabs.network/docs/wallet/exiting-a-validator)
* [Exiting a Nimbus validator](https://nimbus.guide/voluntary-exit.html)
* [Exiting a Lodestar validator](https://chainsafe.github.io/lodestar/run/validator-management/validator-cli#validator-voluntary-exit)
* [Exiting a Lighthouse validator](https://lighthouse-book.sigmaprime.io/voluntary-exit.html)


# Verifying Your Mnemonic Phrase

Ensure you can regenerate the same eth2 key pairs by restoring your `validator_keys`

{% hint style="info" %}
**Offline Key Verifying Best Practices**: The mnemonic seed (24 words) to your validator should be protected by keeping them offline.

If this is not possible, at least physically disconnect from the network by unplugging ethernet cable or disconnecting from Wifi.
{% endhint %}

Using the pre-built staking-deposit-cli executable,

```bash
cd $HOME/ethstaker_deposit-cli
./deposit existing-mnemonic --chain mainnet
```

{% hint style="info" %}
When the **pubkey** in both **keystore** files are **identical**, this means your mnemonic phrase is veritably correct. Other fields will be different because of salting.
{% endhint %}


# Adding a New Validator to an Existing Setup with Existing Seed Words

Scenario: Genesis block is long passed and now you would like to add more validators with your existing mnemonic seed.

## :white\_check\_mark: Requirements

Before continuing please have the following ready:

* Existing 24 word validator mnemonic phrase
* Existing keystore password
* ETH Withdrawal Address from your hardware wallet

### Step 1: Create new deposit\_data json file and new validator\_keys&#x20;

In this example, using the `staking-deposit-cli` tool, you can add more validators by creating a new deposit data file and `validator_keys`&#x20;

{% hint style="warning" %}
**Security recommendation reminder**: For best security practices, key management and other activities where you type your 24 word mnemonic seed should be completed on an air-gapped offline cold machine booted from USB drive.
{% endhint %}

{% hint style="danger" %}
Reminder to use the same **keystore password** as existing validators.
{% endhint %}

For example, in case we originally created **3 validators** but now wish to **add 5 more validators**, we could use the following command.

```bash
# Generate from an existing mnemonic 5 more validators when 3 were previously already made
./deposit existing-mnemonic \
--validator_start_index 3 \
--num_validators 5 \
--chain mainnet \
--execution_address <ETH_ADDRESS_FROM_HARDWARE_WALLET>
```

&#x20;

| Flag                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --validator\_start\_index | Number of validators you ALREADY created                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| --num\_validators         | Number of NEW validators you want to create                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| --chain                   | Options: mainnet holesky goerli                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| --execution\_address      | <p><strong>Critically important</strong>: Your Ethereum Address from a Hardware Wallet. </p><p></p><p>Withdrawals will be sent to this address. If you stop validating and exit your validator, your 32 ETH will be sent here. </p><p></p><p>This <strong>ETH withdrawal address</strong> is one such that <strong>you control the private keys</strong> to, ideally one from a hardware wallet.</p><p></p><p><span data-gb-custom-inline data-tag="emoji" data-code="1f6d1">🛑</span><strong>DO NOT USE A EXCHANGE ADDRESS!</strong><span data-gb-custom-inline data-tag="emoji" data-code="1f6d1">🛑</span></p> |

### Step 2: Deposit 32 ETH per validator

**Option 1**: Visit the [official Ethereum Launchpad site](https://launchpad.ethereum.org)

Two important tasks to complete at the launchpad.

* Upload the `deposit_data-#########.json`
* Make the 32 ETH deposit transaction(s), 32 ETH per validator. 1 deposit transaction per validator.&#x20;

**Option 2**: Use [Abyss's Batch Ethereum Depositor](https://abyss.finance/eth2depositor) to combine many validator deposits into just 1 transaction.

### Step 3: Import New Validator Keys

This step assumes your new validator keys are located in&#x20;

```bash
$HOME/staking-deposit-cli/validator_keys
```

If Wagyu was used to generate validator keys, move the keystore files to the above location.

{% tabs %}
{% tab title="Lighthouse" %}
Stop your validator client.

```bash
sudo systemctl stop validator
```

Import your validator keys by importing your **keystore file**. Be sure to enter your **keystore password** correctly.

```bash
sudo lighthouse account validator import \
  --network mainnet \
  --datadir /var/lib/lighthouse \
  --directory=$HOME/ethstaker_deposit-cli/validator_keys \
  --reuse-password
```

Verify that your keystore file was imported successfully.

<pre class="language-bash"><code class="lang-bash"><strong>sudo lighthouse account_manager validator list \
</strong><strong>  --network mainnet \
</strong>  --datadir /var/lib/lighthouse
</code></pre>

Once successful, you will be shown your **validator's public key**.

For example, `0x8d9138fcf5676e2031dc4eae30a2c92e3306903eeec83ca83f4f851afbd4cb3b33f710e6f4ac516b4598697b30b04302`

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/lighthouse/validators
sudo chmod 700 /var/lib/lighthouse/validators
```

Finally, start your validator client.

```bash
sudo systemctl restart validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
INFO Enabled validator          voting_pubkey: 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf, signing_method: local_keystore
INFO Enabled validator          voting_pubkey: 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866, signing_method: local_keystore
INFO Initialized validators     enabled: 2, disabled: 0
```

{% endtab %}

{% tab title="Lodestar" %}
Stop your validator client.

```bash
sudo systemctl stop validator
```

Import your validator keys by importing your **keystore file**. Be sure to enter your **keystore password** correctly.

```bash
cd /usr/local/bin/lodestar
sudo ./lodestar validator import \
  --network mainnet \
  --dataDir="/var/lib/lodestar/validators" \
  --keystore=$HOME/ethstaker_deposit-cli/validator_keys
```

Verify that your keystore file was imported successfully.

```bash
sudo ./lodestar validator list \
  --network mainnet \
  --dataDir="/var/lib/lodestar/validators"
```

Once successful, you will be shown your **validator's public key**.

For example, `0x8d9138fcf5676e2031dc4eae30a2c92e3306903eeec83ca83f4f851afbd4cb3b33f710e6f4ac516b4598697b30b04302`

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/lodestar/validators
sudo chmod 700 /var/lib/lodestar/validators
```

Finally, restart to use the new validators.

```bash
sudo systemctl restart validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
info: 100% of local keystores imported. current=2 total=2 rate=975.61keys/m
info: 2 local keystores
info: 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf
info: 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866
```

Press `Ctrl` + `C` to exit the logs.
{% endtab %}

{% tab title="Teku" %}

<details>

<summary>Option 1: For standalone validator</summary>

Stop your Teku client.

```bash
sudo systemctl stop validator
```

Storing your **keystore password** in a text file is required so that Teku can decrypt and load your validators automatically.

Create a temporary file to store your **keystore password**. Type your password in this file.

```bash
sudo nano $HOME/validators-password.txt
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Confirm that your **keystore password** is correct.

```bash
sudo cat $HOME/validators-password.txt
```

Run the following command to create a corresponding password file for every one of your validators.

```bash
for f in $HOME/ethstaker_deposit-cli/validator_keys/keystore*.json; do sudo cp $HOME/validators-password.txt $HOME/ethstaker_deposit-cli/validator_keys/$(basename $f .json).txt; done
```

Copy keystores to validator folder

```bash
sudo cp $HOME/ethstaker_deposit-cli/validator_keys/keystore* /var/lib/teku_validator/validator_keys
```

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/teku_validator
sudo chmod -R 700 /var/lib/teku_validator
```

Verify that your validator's keystore .json files and validator's passwords .txt files are present by checking the following directory.

```bash
sudo ls -l /var/lib/teku_validator/validator_keys
```

Example output of two validator's keystore.json files with matching password.txt files.

```
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.txt
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.txt
```

Delete the temporary **keystore password** file.

```bash
sudo rm $HOME/validators-password.txt
```

Finally, restart Teku to use the new validators.

```bash
sudo systemctl restart validator
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
INFO  - Loading 2 validator keys...
INFO  - Loaded 2 Validators: 95d3986, 82b225f
```

</details>

<details>

<summary>Option 2: For Combined CL+VC</summary>

Stop your Teku client.

```bash
sudo systemctl stop consensus
```

Storing your **keystore password** in a text file is required so that Teku can decrypt and load your validators automatically.

Create a temporary file to store your **keystore password**. Type your password in this file.

```bash
sudo nano $HOME/validators-password.txt
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Confirm that your **keystore password** is correct.

```bash
sudo cat $HOME/validators-password.txt
```

Run the following command to create a corresponding password file for every one of your validators.

```bash
for f in $HOME/ethstaker_deposit-cli/validator_keys/keystore*.json; do sudo cp $HOME/validators-password.txt $HOME/ethstaker_deposit-cli/validator_keys/$(basename $f .json).txt; done
```

Copy keystores to validator folder

```bash
sudo cp $HOME/ethstaker_deposit-cli/validator_keys/keystore* /var/lib/teku/validator_keys
```

Setup ownership permissions, including hardening the access to this directory.

<pre class="language-bash"><code class="lang-bash">sudo chown -R consensus:consensus /var/lib/teku/
<strong>sudo chmod -R 700 /var/lib/teku/validator_keys
</strong></code></pre>

Verify that your validator's keystore .json files and validator's passwords .txt files are present by checking the following directory.

```bash
sudo ls -l /var/lib/teku/validator_keys
```

Example output of two validator's keystore.json files with matching password.txt files.

```
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.txt
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.txt
```

Delete the temporary **keystore password** file.

```bash
sudo rm $HOME/validators-password.txt
```

Finally, restart Teku to use the new validators.

```bash
sudo systemctl restart consensus
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu consensus | ccze
```

For example when using 2 validators, logs will show the following:

```bash
INFO  - Loading 2 validator keys...
INFO  - Loaded 2 Validators: 95d3986, 82b225f
```

</details>
{% endtab %}

{% tab title="Nimbus" %}

<details>

<summary>Option 1: For standalone validator</summary>

Stop your Nimbus client.

```bash
sudo systemctl stop validator
```

Enter your **keystore password** to import accounts.

```bash
sudo /usr/local/bin/nimbus_beacon_node deposits import \
  --data-dir=/var/lib/nimbus_validator $HOME/ethstaker_deposit-cli/validator_keys
```

Now you can verify the accounts were imported successfully by doing a directory listing.

```bash
sudo ls -l /var/lib/nimbus_validator/validators
```

You should see a folder named for each of your validator's pubkey.

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/nimbus_validator
sudo chmod -R 700 /var/lib/nimbus_validator
```

Finally, restart Nimbus to use the new validators.

```bash
sudo systemctl restart validator
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
Loading validators             topics="beacval" validatorsDir=/var/lib/nimbus/validators keystore_cache_available=true
Local validator attached       topics="val_pool" pubkey=95d39860a0d6ea3b92cba78069d21f3a validator=95d39860 initial_fee_recipient=81ba8d5c4ae850
Local validator attached       topics="val_pool" pubkey=82b225f66476962b161ed015786df00f validator=82b225f6 initial_fee_recipient=81ba8d5c4ae850
```

</details>

<details>

<summary>Option 2: For Combined CL+VC</summary>

Stop your Nimbus client.

```bash
sudo systemctl stop consensus
```

Enter your **keystore password** to import accounts.

```bash
sudo /usr/local/bin/nimbus_beacon_node deposits import \
  --data-dir=/var/lib/nimbus $HOME/ethstaker_deposit-cli/validator_keys
```

Now you can verify the accounts were imported successfully by doing a directory listing.

```bash
sudo ls -l /var/lib/nimbus/validators
```

You should see a folder named for each of your validator's pubkey.

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R consensus:consensus /var/lib/nimbus
sudo chmod -R 700 /var/lib/nimbus
```

Finally, restart Nimbus to use the new validators.

```bash
sudo systemctl restart consensus
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu consensus | ccze
```

For example when using 2 validators, logs will show the following:

```bash
Loading validators             topics="beacval" validatorsDir=/var/lib/nimbus/validators keystore_cache_available=true
Local validator attached       topics="val_pool" pubkey=95d39860a0d6ea3b92cba78069d21f3a validator=95d39860 initial_fee_recipient=81ba8d5c4ae850
Local validator attached       topics="val_pool" pubkey=82b225f66476962b161ed015786df00f validator=82b225f6 initial_fee_recipient=81ba8d5c4ae850
```

</details>
{% endtab %}

{% tab title="Prysm" %}
Stop your validator client.

```bash
sudo systemctl stop validator
```

Import your validator keys by importing your **keystore file**. When asked to create a new wallet password, enter your **keystore password**. When prompted for the imported accounts password, enter your **keystore password** again.

If using Binaries,

```shell
sudo /usr/local/bin/validator accounts import \
  --accept-terms-of-use \
  --mainnet \
  --wallet-dir=/var/lib/prysm/validators \
  --keys-dir=$HOME/ethstaker_deposit-cli/validator_keys
```

If Built from Source,

```bash
cd /usr/local/bin/prysm
sudo bazel run //validator:validator -- accounts import \
  --accept-terms-of-use \
  --mainnet \
  --wallet-dir=/var/lib/prysm/validators \
  --keys-dir=$HOME/ethstaker_deposit-cli/validator_keys
```

Verify that your keystore file was imported successfully.

If using Binaries,

```bash
sudo /usr/local/bin/validator accounts list \
  --wallet-dir=/var/lib/prysm/validators \
  --mainnet
```

If Built from Source,

<pre class="language-bash"><code class="lang-bash"><strong>cd /usr/local/bin/prysm
</strong><strong>sudo bazel run //validator:validator -- accounts list \
</strong>  --wallet-dir=/var/lib/prysm/validator \
  --mainnet
</code></pre>

Once successful, you will be shown your **validator's public key**. For example:

```
Showing 2 validator accounts
View the eth1 deposit transaction data for your accounts by running `validator accounts list --show-deposit-data`

Account 0 | gently-learning-chamois
[validating public key] 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866

Account 1 | presumably-powerful-lynx
[validating public key] 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf
```

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/prysm/validators
sudo chmod 700 /var/lib/prysm/validators
```

Finally, restart Prsym validator to use the new validators.

```bash
sudo systemctl restart validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
level=info msg="Validating for public key" prefix=validator publicKey=0x95d39860a0d6
level=info msg="Validating for public key" prefix=validator publicKey=0x82b225f66476

```

{% endtab %}
{% endtabs %}

### Step 4: Backup and Delete `validator_keys` directory

Make backup copies of your validator\_keys directory to USB media or other devices. These validator keys can always be regenerated from secret recovery mnemonic phrase.

Afterwards, you may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/staking-deposit-cli/validator_keys
```

### Step 5: Estimate when your new validator becomes active

Your additional validators are now in the activation queue waiting their turn. Check the "**Entry Queue**" for your estimated wait time at [https://www.validatorqueue.com](https://www.validatorqueue.com/)

In the below example, the wait time was approximately 11 days, 1 hour until a new validator became active.

<figure><img src="/files/exJVCox6cufJEJJJo2bc" alt=""><figcaption><p>Entry Queue</p></figcaption></figure>


# Switching / Migrating Consensus Client

{% hint style="info" %}
The key takeaway in this process is to avoid running two validator clients simultaneously. You want to avoid being punished by a slashing penalty, which causes a loss of ether.
{% endhint %}

#### :octagonal\_sign: 1 Stop old consensus and old validator.

In order to export the slashing database, the validator needs to be stopped.

{% tabs %}
{% tab title="Lighthouse | Prysm | Lodestar" %}

```bash
sudo systemctl stop consensus validator
```

{% endtab %}

{% tab title="Nimbus | Teku" %}

```
sudo systemctl stop consensus
```

{% endtab %}
{% endtabs %}

#### :minidisc: 2 Export slashing database (Optional)

{% hint style="info" %}
[EIP-3076](https://eips.ethereum.org/EIPS/eip-3076) implements a standard to safety migrate validator keys between consensus clients. This is the exported contents of the slashing database.
{% endhint %}

Update the export .json file location and name.

{% tabs %}
{% tab title="Lighthouse" %}

```bash
sudo -u consensus /usr/local/bin/lighthouse account validator slashing-protection export <lighthouse_interchange.json>
```

{% endtab %}

{% tab title="Nimbus" %}

```bash
sudo -u consensus /usr/local/bin/nimbus_beacon_node slashingdb export slashing-protection.json

```

{% endtab %}

{% tab title="Teku" %}

```bash
sudo -u consensus /usr/local/bin/teku/bin/teku slashing-protection export --to=<FILE>
```

{% endtab %}

{% tab title="Prysm" %}

```bash
sudo -u validator /usr/local/bin/validator slashing-protection export --datadir=/path/to/your/wallet --slashing-protection-export-dir=/path/to/desired/outputdir
```

{% endtab %}

{% tab title="Lodestar" %}

```bash
sudo -u validator /usr/local/bin/lodestar/lodestar validator slashing-protection export --network mainnet --file interchange.json
```

{% endtab %}
{% endtabs %}

#### :construction: 3 Setup and install new validator / consensus client

Now you need to setup/install your new validator **but do not start running the systemd processes**. Be sure to thoroughly follow your new consensus client and validator in steps 4 and 5. You will need to build/install the client, configure port forwarding/firewalls, and new systemd unit files.

{% hint style="warning" %}
:sparkles: **Pro Tip**: During the process of re-importing validator keys, **wait at least 13 minutes** or two epochs to prevent slashing penalties. You must avoid running two consensus clients with same validator keys at the same time.
{% endhint %}

{% hint style="danger" %}
:octagonal\_sign: **Critical Step**: Do not start any **systemd processes** until either you have imported the slashing database or you have **waited at least 13 minutes or two epochs**.
{% endhint %}

#### :open\_file\_folder: 4 Import slashing database (Optional)

Using your new consensus client, run the following command and update the relevant path to import your slashing database from 2 steps ago.

{% tabs %}
{% tab title="Lighthouse" %}

```bash
sudo -u consensus /usr/local/bin/lighthouse account validator slashing-protection import <my_interchange.json>
```

{% endtab %}

{% tab title="Nimbus" %}

```bash
sudo -u consensus /usr/local/bin/nimbus_beacon_node slashingdb import path/to/export_dir/slashing-protection.json
```

{% endtab %}

{% tab title="Teku" %}

```bash
sudo -u consensus /usr/local/bin/teku/bin/teku slashing-protection import --from=<FILE>
```

{% endtab %}

{% tab title="Prysm" %}

```bash
sudo -u validator /usr/local/bin/validator slashing-protection import --datadir=/path/to/your/wallet --slashing-protection-json-file=/path/to/desiredimportfile
```

{% endtab %}

{% tab title="Lodestar" %}

```bash
sudo -u validator /usr/local/bin/lodestar/lodestar validator slashing-protection import --network mainnet --file interchange.json
```

{% endtab %}
{% endtabs %}

#### :stars: 5 Start new validator and new beacon chain

{% tabs %}
{% tab title="Lighthouse | Prysm | Lodestar" %}

```bash
sudo systemctl start consensus validator
```

{% endtab %}

{% tab title="Nimbus | Teku" %}

```
sudo systemctl start consensus
```

{% endtab %}
{% endtabs %}

#### :fire: 6 Verify functionality

Check the logs to verify the services are working properly and ensure there are no errors.

{% tabs %}
{% tab title="Lighthouse | Prysm | Lodestar" %}

```bash
sudo systemctl status consensus validator
```

{% endtab %}

{% tab title="Nimbus | Teku" %}

```
sudo systemctl status consensus
```

{% endtab %}
{% endtabs %}

Finally, verify your validator's attestations are working with public block explorer such as

[https://beaconcha.in/](https://beaconcha.in)

Enter your validator's pubkey to view its status.

#### :fire\_extinguisher: 7 Update Monitoring with Prometheus and Grafana

[Review section 6](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/monitoring-your-validator-with-grafana-and-prometheus) and change your `prometheus.yml`. Ensure prometheus is connected to your new consensus client's metrics port. You will also want to import your new consensus client's dashboard.


# Switching / Migrating Execution Client

{% hint style="info" %}
Important reasons why you would want to switch Execution Clients:

:owl: **Client Diversity**: Improve Ethereum's resilience by using a [minority client](https://mirror.xyz/jmcook.eth/S7ONEka_0RgtKTZ3-dakPmAHQNPvuj15nh0YGKPFriA)

:floppy\_disk: **Unique Features**: Each client has their own strengths, i.e. faster sync, lower resource requirements, different programming language, unique abilities
{% endhint %}

{% hint style="info" %}
:fire:**Optional Tip**: Before switching, it is possible to minimize downtime and keep your validator online by using a failover node, either your own EL/CL stack, or a public service.

Here are some public options:

* [RocketPool's Rescue Node](https://rescuenode.com/docs/how-to-connect/solo)
* [Tennisbowling's Open Execution Node](https://openexecution.tennisbowling.com/)

However, as validator downtime incurs minimal penalties, the added complexity might not be worth your time and extra work configuring a failover option.
{% endhint %}

{% hint style="info" %}
The following steps align with our [mainnet guide](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet). You may need to adjust file names and directory locations where appropriate. The core concepts remain the same.
{% endhint %}

## Option 1: Automated One-Liner

Simply copy and paste the command into your terminal.

Open source source code available here: <https://github.com/coincashew/client-switcher>

```bash
sudo /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/client-switcher/master/install.sh)"
```

<figure><img src="/files/Cn4pA353omPqy8CNLXru" alt=""><figcaption><p>One-liner screenshot</p></figcaption></figure>

## Option 2: Manual Method

<details>

<summary>Step 1: Remove OLD Execution Client</summary>

Stop execution client and remove the service user, data paths, binaries and service files.

```bash
# Stop Execution Client
sudo systemctl stop execution
sudo systemctl disable execution

# Remove service file
sudo rm /etc/systemd/system/execution.service

# Nethermind
sudo rm -rf /usr/local/bin/nethermind
sudo rm -rf /var/lib/nethermind

# Besu
sudo rm -rf /usr/local/bin/besu
sudo rm -rf /var/lib/besu

# Geth
sudo rm -rf /usr/local/bin/geth
sudo rm -rf /var/lib/geth

# Erigon
sudo rm -rf /usr/local/bin/erigon
sudo rm -rf /var/lib/erigon

# Reth
sudo rm -rf /usr/local/bin/reth
sudo rm -rf /var/lib/reth

# Remove service user
sudo userdel execution
```

</details>

<details>

<summary>Step 2: Install NEW Execution Client</summary>

Follow the instructions found under section: [Installing a new Execution Client.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-3-installing-execution-client)

***

:fire:**Tip**: As well as being a minority client, **Nethermind** is known to be incredibly fast at syncing, often as quick as 2 hours with fast NVME drives.

</details>

<details>

<summary>Step 3: Restart Consensus Client</summary>

Ensure the consensus client establishes a connection to the new execution client.

```bash
sudo systemctl restart consensus
```

</details>

<details>

<summary>Step 4: Update Monitoring tools</summary>

**Promentheus and Grafana**:

* Revisit the [monitoring guide](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/monitoring-your-validator-with-grafana-and-prometheus) and update your `prometheus.yml`configuration for the new execution client.
* Ensure prometheus is connected to your new execution client's metrics port 6060.
* Also import your new execution client's dashboard.

**Beaconcha.in Mobile App:**

* To receive new notifications, update your app's settings to indicate you're using a different execution client

</details>

{% hint style="success" %}
Congrats on switching to a new execution client!
{% endhint %}


# Using Node as RPC URL endpoint

How to connect your ETH wallet to your own node's RPC endpoint

### :tada: Reasons to use your own NODE as RPC URL endpoint

* **Privacy**: No spying by middleman between you and the blockchain
* **Trustless verification**: Ability to verify the ETH transaction data you see is raw and not manipulated
* **Decentralization**: No need to depend on Infura or other centralized 3rd parties
* **Coolness and credibility**: Using Ethereum as it was meant to be, a step towards being more sovereign

### :robot: How to use your NODE as a RPC endpoint

{% hint style="info" %}
Before continuing please understand the following:

* As this method uses SSH tunneling, no changes are required to your firewall or router's port forwarding
  {% endhint %}

### 1. Verify RPC port 8545 is listening

Double check that your node is listening on port 8545&#x20;

```bash
ss -ntlp | grep 8545
```

For example, here's the output for Besu with RPC enabled.

```bash
LISTEN 0      128    [::ffff:127.0.0.1]:8545             *:*    users:(("java",pid=26453,fd=433))
```

{% hint style="warning" %}
**Port 8545 is NOT listening or using Geth or Besu?**

**Note: Nethermind** and **Erigon** enable RPC by default.

The following flags on the `ExecStart` line are required to enable RPC.

**Geth**

```bash
--http
```

**Besu**

```bash
--rpc-http-enabled=true
--rpc-http-cors-origins="*"
```

Changes can be made to the **systemd unit file** `execution.service,`

```bash
sudo nano /etc/systemd/system/execution.service
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Make sure to reload and restart.

```bash
sudo systemctl daemon-reload
sudo systemctl restart execution
```

{% endhint %}

### 2. Create a SSH tunnel

{% hint style="info" %}
Every time you want to use your node as an RPC endpoint, you must open a SSH tunnel connection with port 8545 forwarded.

**Exception:** **Local nodes** (i.e. using Ubuntu Desktop) - if you're accessing your wallet on the same machine as your node, skip this step.
{% endhint %}

{% tabs %}
{% tab title="Linux or MacOS" %}
Example of how to create a SSH tunnel in Linux or MacOS:

```bash
ssh -N -v <user>@<staking.node.ip.address> -L 8545:localhost:8545

#Full Example
ssh -N -v ethereum@192.168.1.69 -L 8545:localhost:8545
```

{% endtab %}

{% tab title="Windows" %}
Example of how to create a SSH tunnel in Windows with [Putty](https://putty.org/):

Navigate to Connection > SSH > Tunnels > Enter Source Port `8545`> Enter Destination `localhost:8545`> Click Add

![](/files/JDqrTGxjIxTavVhRSmCk)

Now save your configuration. Navigate to Session > Enter a session name > Save

Click Open to open a connection
{% endtab %}
{% endtabs %}

### 3. Configure wallet to use RPC URL

When configuring your wallet, you can reference the following network information:

| Network     | Chain ID | Block Explorer                                                | Currency   |
| ----------- | -------- | ------------------------------------------------------------- | ---------- |
| **Mainnet** | 1        | <https://etherscan.io>                                        | ETH        |
| **Holešky** | 17000    | [https://holesky.etherscan.io](https://holesky.etherscan.io/) | HoleskyETH |
| **Goerli**  | 5        | <https://goerli.etherscan.io>                                 | GoerliETH  |
| **Sepolia** | 11155111 | <https://sepolia.etherscan.io>                                | SepoliaETH |

Here are steps to configure popular wallets to use a custom RPC URL endpoint.

<details>

<summary>Rabby</summary>

Download from [https://rabby.io](https://rabby.io/)

1. Click **More**
2. Click **Custom RPC**
3. Click **Add RPC**
4. Select the network. If testnet, you might need to go back a menu and enable testnets.
5. Fill in the **RPC URL** as **<http://127.0.0.1:8545>**
6. Rabby will now show your balances with this RPC.

Example of Adding a Network:

![](/files/ON9RyhKsRUc3Aw3HlOhG)

</details>

<details>

<summary>Frame</summary>

Download from [https://frame.sh](https://frame.sh/)

1. Open **Chains**
2. Either add to an existing chain (i.e. Mainnet) or Click "**Add New Chain"**
3. Fill in **Primary (if new chain) or Secondary (if existing chain) RPC URL** as **<http://localhost:8545>**
4. If required, fill in **Chain name**, **Chain ID**, **Native symbol**, **Native Currency Name** and **Block Explorer** with data from above table
5. Click **ADD CHAIN button**
6. Frame will now display your balances with this RPC.

Example of Adding a Network:

![](/files/jr2pcGYw1BtdPdHuv9bP)

</details>

<details>

<summary>Metamask</summary>

Download from [https://metamask.io](https://metamask.io/)

1. Open **Settings**
2. Open **Networks**
3. Click "**Add a network**" > **Add a network manually**
4. Fill in **New RPC URL** as **<http://localhost:8545>**
5. Fill in **Network name**, **Chain ID**, **Currency symbol**, and **Block Explorer** with data from above table
6. Click **Save button**
7. Finally, click the top left button and "**Select a Network**", the network which you just added.

Example of Adding a Network:

![](/files/VJhztVPXiVieLPmi80zY)

</details>

{% hint style="success" %}
Great job! You're now using your own node as your own RPC URL endpoint.
{% endhint %}


# Using All Available LVM Disk Space

During installation of Ubuntu Server, a common issue arises where your hard drive's space is not fully available for use.

<pre class="language-bash"><code class="lang-bash"># View your disk drives
sudo -s lvm

# Change the logical volume filesystem path if required
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

#exit lvextend
exit

# Resize file system to use the new available space in the logical volume
<strong>sudo resize2fs /dev/ubuntu-vg/ubuntu-lv
</strong>
## Verify new available space
df -h

# Example output of a 2TB drive where 25% is used
# Filesystem                         Size   Used Avail Use% Mounted on
# /dev/ubuntu-vg/ubuntu-lv           2000G  500G  1500G  25% /
</code></pre>

**Source reference**: <https://askubuntu.com/questions/1106795/ubuntu-server-18-04-lvm-out-of-space-with-improper-default-partitioning>


# Reducing Network Bandwidth Usage

{% hint style="info" %}
Hosting your own execution client can consume hundreds of gigabytes of data per day. Because data plans can be limited or costly, you might desire to slow down data usage but still maintain good connectivity to the network.
{% endhint %}

Edit your execution.service unit file.

```bash
sudo nano /etc/systemd/system/execution.service
```

Add the following flag to limit the number of peers on the `ExecStart` line.

{% tabs %}
{% tab title="Geth" %}

```bash
--maxpeers 10

# Example
# ExecStart=/usr/local/bin/geth --maxpeers 10
```

{% endtab %}

{% tab title="Besu" %}

```bash
--max-peers 10

# Example
# ExecStart=/usr/local/bin/besu/bin/besu --max-peers 10
```

{% endtab %}

{% tab title="Nethermind" %}

```bash
--Network.MaxActivePeers 10

# Example
# ExecStart=/usr/local/bin/nethermind/Nethermind.Runner --Network.MaxActivePeers 10
```

{% endtab %}

{% tab title="Erigon" %}

```bash
--maxpeers 10

# Example
# ExecStart=/usr/local/bin/erigon --maxpeers 10
```

{% endtab %}

{% tab title="Reth" %}

```bash
--max-outbound-peers 15 --max-inbound-peers 10

# Example
# ExecStart=/usr/local/bin/reth node --max-outbound-peers 15 --max-inbound-peers 10
```

{% endtab %}
{% endtabs %}

Finally, reload the new unit file and restart the execution client.

```bash
sudo systemctl daemon-reload
sudo systemctl restart execution
```


# How to re-sync using checkpoint sync

{% hint style="info" %}
Common reasons for re-syncing include:

:owl: **Missed upgrade**: Hard fork occurred and I forgot to update my consensus client

:floppy\_disk: **Low disk space**: I'm running low on disk space and would like to recover space
{% endhint %}

<details>

<summary>Step 1: Stop consensus client</summary>

```
sudo systemctl stop consensus
```

</details>

<details>

<summary>Step 2: Remove consensus client database directory</summary>

Prysm

```
sudo rm -r /var/lib/prysm/beacon/beaconchaindata
```

Lodestar

```
sudo rm -r /var/lib/lodestar/chain-db
```

Teku

```
sudo rm -r /var/lib/teku/beacon
```

Nimbus

```
sudo rm -r /var/lib/nimbus/db
```

Lighthouse

```
sudo rm -r /var/lib/lighthouse/beacon
```

</details>

<details>

<summary>Step 3: Ensure a checkpoint sync server is configured</summary>

* Below examples use the default checkpoint sync endpoint <https://beaconstate.info>
* Refer to [https://eth-clients.github.io/checkpoint-sync-endpoints](https://eth-clients.github.io/checkpoint-sync-endpoints/) and pick another random state providers from the list, if desired.
* Do not trust any single checkpoint provider. Verify the state root and block root against multiple checkpoints to ensure you're on the correct chain.

### **Nimbus**:

Run the following to start the checkpoint sync.

```bash
sudo -u consensus /usr/bin/nimbus_beacon_node trustedNodeSync \
--network=mainnet  \
--trusted-node-url=https://beaconstate.info \
--data-dir=/var/lib/nimbus \
--network=mainnet \
--backfill=false
```

When the nimbus checkpoint sync is complete, you'll see the following message:

```
Done, your beacon node is ready to serve you! Don't forget to check that you're on the canonical chain by comparing the checkpoint root with other online sources. See https://nimbus.guide/trusted-node-sync.html for more information.
```

### **Teku**:

Edit your config file

```
sudo nano /etc/systemd/system/consensus.service
```

Ensure the following line is listed

```
--initial-state="https://beaconstate.info/eth/v2/debug/beacon/states/finalized"
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

### **Lighthouse**:

Edit your service file

```
sudo nano /etc/systemd/system/consensus.service
```

Ensure the following line is listed on your `ExecStart` line

```
--checkpoint-sync-url=https://beaconstate.info
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

### **Prysm**:

Edit your service file

```
sudo nano /etc/systemd/system/consensus.service
```

Ensure the following line is listed on your `ExecStart` line

```
--checkpoint-sync-url=https://beaconstate.info
--genesis-beacon-api-url=https://beaconstate.info
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

### **Lodestar**:

Edit your service file

```
sudo nano /etc/systemd/system/consensus.service
```

Ensure the following line is listed on your `ExecStart` line

```
--checkpointSyncUrl https://lodestar-mainnet.chainsafe.io
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

</details>

<details>

<summary>Step 4: Start consensus client</summary>

```
sudo systemctl daemon-reload
sudo systemctl restart consensus
```

</details>

<details>

<summary>Step 5: Check the beacon chain logs and ensure sync is on right chain</summary>

Verify that you are on the correct chain by visiting [https://eth-clients.github.io/checkpoint-sync-endpoints](https://eth-clients.github.io/checkpoint-sync-endpoints/) and selecting a **different** endpoint link. Verify that your log's are in agreement with the other endpoint's `epoch / slot / state root / block root`

View your logs:

```
sudo journalctl -fu consensus
```

Checkpoint sync should take no more than a few minutes to re-sync. Your execution client may take longer to catch up.

</details>

{% hint style="success" %}
Congrats! You've successfully re-synced your consensus client.
{% endhint %}


# Important Directory Locations

{% hint style="info" %}
In case you need to locate your validator keys, database directories or other important files.
{% endhint %}

#### Consensus engine files and locations

{% tabs %}
{% tab title="Lighthouse" %}

```bash
# Validator Keys
/var/lib/lighthouse/validators

# Beacon Chain Data
/var/lib/lighthouse/beacon

# List of all validators and passwords
/var/lib/lighthouse/validators/validator_definitions.yml

#Slash protection db
/var/lib/lighthouse/validators/slashing_protection.sqlite
```

{% endtab %}

{% tab title="Nimbus" %}

```bash
# Validator Keys
/var/lib/nimbus/validators

# Beacon Chain Data
/var/lib/nimbus/db

#Slash protection db
/var/lib/nimbus/validators/slashing_protection.sqlite3

#Logs
/var/lib/nimbus/beacon.log
```

{% endtab %}

{% tab title="Teku" %}

```bash
# Validator Keys
/var/lib/teku

# Beacon Chain Data
/var/lib/teku/beacon

#Slash protection db
/var/lib/teku/validator/slashprotection
```

{% endtab %}

{% tab title="Prysm" %}

```bash
# Validator Keys
/var/lib/prysm/validators

# Beacon Chain Data
/var/lib/prysm/beacon/beaconchaindata
```

{% endtab %}

{% tab title="Lodestar" %}

```bash
# Validator Keystores
/var/lib/lodestar/validators

# Validator DB Data
/var/lib/lodestar/validators

# Beacon Chain Data
/var/lib/lodestar/chain-db
```

{% endtab %}
{% endtabs %}

#### Execution engine files and locations

{% tabs %}
{% tab title="Geth" %}

```bash
# database location
/var/lib/geth
```

{% endtab %}

{% tab title="Besu" %}

```bash
# database location
/var/lib/besu
```

{% endtab %}

{% tab title="Nethermind" %}

```bash
#database location
/var/lib/nethermind
```

{% endtab %}

{% tab title="Erigon" %}

```bash
#database location
/var/lib/erigon
```

{% endtab %}
{% endtabs %}


# Improving Validator Attestation Effectiveness

{% hint style="info" %}
Learn about [attestation effectiveness from Attestant.io](https://www.attestant.io/posts/defining-attestation-effectiveness/)
{% endhint %}

#### :family\_mwgg: Strategy: Increase beacon chain peer count

{% hint style="info" %}
This change will result in increased bandwidth and memory usage. Tweak and tailor appropriately for your hardware.

*Kudos to* [*Rémy Roy*](https://www.reddit.com/user/remyroy/) *for this strat.*
{% endhint %}

Edit your consensus.`service` unit file.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Add the following flag to increase peers on the `ExecStart` line.

{% tabs %}
{% tab title="Lighthouse" %}

```bash
--target-peers 100
# Example
# lighthouse bn --target-peers 100 --staking --metrics --network mainnet
```

{% endtab %}

{% tab title="Nimbus" %}

```bash
--max-peers=100
# Example
# /usr/bin/nimbus_beacon_node --network=mainnet --max-peers=100
```

{% endtab %}

{% tab title="Teku" %}

```bash
--p2p-peer-upper-bound 100
```

{% endtab %}

{% tab title="Prysm" %}

```bash
--p2p-max-peers=100
# Example
# prysm.sh beacon-chain --mainnet --p2p-max-peers=100 --http-web3provider=http://127.0.0.1:8545 --accept-terms-of-use 
```

{% endtab %}

{% tab title="Lodestar" %}

```bash
--network.maxPeers 100
# Example
# ./lodestar beacon --network.maxPeers 100 --network mainnet
```

{% endtab %}
{% endtabs %}

Reload the updated unit file and restart the beacon-chain process to complete this change.

```bash
sudo systemctl daemon-reload
sudo systemctl restart consensus
```

#### :gear: Strategy: Perform updates or reboots during the longest attestation gap

Learn how to at [this quick guide.](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance/finding-the-longest-attestation-slot-gap)


# EIP2333 Key Generator by iancoleman.io

A [key generator tool by iancoleman](https://iancoleman.io/eip2333/) can generate EIP2333 keys from a BIP39 mnemonic, or a seed, or a master secret key.

This tool should be used **offline** and is useful for extracting **withdrawal keys** and **signing keys**.

Link: <https://iancoleman.io/eip2333/>

{% hint style="info" %}
For more info see the [EIP2333 spec](https://eips.ethereum.org/EIPS/eip-2333).
{% endhint %}


# Geth - Enabling path-based state storage

No more offline pruning, save time and disk space!

{% hint style="info" %}
As of [Geth v1.13.0](https://blog.ethereum.org/2023/09/12/geth-v1-13-0), a new database model for storing the Ethereum state, which is both faster than the previous scheme, and also has proper pruning implemented.&#x20;

No more junk accumulating on disk and no more guerilla (offline) pruning!
{% endhint %}

### :tada: Enjoy performance improvements

<figure><img src="/files/4mH36n5C2QYCLo7ZjfRw" alt=""><figcaption></figcaption></figure>

### :robot: How to enable PBSS for existing installations

{% hint style="info" %}
Before continuing please understand the following:

* Synching Geth can take hours during which time block proposals can be missed
* Consider using a backup EL/CL if you have many validators
* Enabling PBSS requires a full Geth resync
  {% endhint %}

{% tabs %}
{% tab title="V2 Staking Setup (Current)" %}

```bash
# Stop geth
sudo systemctl stop execution

#(add --state.scheme=path to the ExecStart line)
sudo nano /etc/systemd/system/execution.service

# reload changes
sudo systemctl daemon-reload

# Delete the old db
# and when asked, delete the state database, but keep the ancient database
# Yes to state db, no to ancient db.
sudo -u execution /usr/local/bin/geth --datadir /var/lib/geth removedb

# Start geth
sudo systemctl start execution
```

{% endtab %}

{% tab title="V1 Staking Setup" %}

```bash
# Stop geth
sudo systemctl stop eth1

#(add --state.scheme=path to the ExecStart line)
sudo nano /etc/systemd/system/eth1.service

# reload changes
sudo systemctl daemon-reload

# Delete the old db
# and when asked, delete the state database, but keep the ancient database
# Yes to state db, no to ancient db.
sudo /usr/bin/geth --datadir ~/.ethereum removedb

# Start geth
sudo systemctl start eth1
```

{% endtab %}
{% endtabs %}

Example of V2 service file with updated ExecStart line using `--state.scheme=path`

```bash
[Unit]
Description=Geth Execution Layer Client service for Mainnet
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/geth \
    --mainnet \
    --metrics \
    --datadir=/var/lib/geth \
    --pprof \
    --state.scheme=path \
    --authrpc.jwtsecret=/secrets/jwtsecret
   
[Install]
WantedBy=multi-user.target
```


# Disk Usage by Execution / Consensus Client

EL and CL combinations ranked by disk usage

### Summary

As of late 2022, here is a sampling of EL/CL combinations and their disk space usage. Sorted by highest to lowest disk usage, from a glance you can determine relatively how much space each client combination required at that time and hopefully help you make better informed decisions.

<details>

<summary>Mainnet tldr</summary>

**Least disk space use:** Besu/Teku 577GB

**Most disk space use**: Erigon/Lodestar 1.6TB

</details>

<details>

<summary>Testnet Goerli tldr</summary>

**Least disk space use:** Besu/Prysm

**Most disk space use**: Erigon/Nimbus

</details>

### Mainnet

{% hint style="info" %}
Execution and consensus layer data usage numbers as of 2022.12.19 by barnabas
{% endhint %}

| Disk Use | CL EL Combination     |
| -------- | --------------------- |
| 1.6T     | erigon-lodestar       |
| 1.6T     | erigon-prysm          |
| 1.5T     | erigon-nimbus         |
| 1.5T     | erigon-lighthouse     |
| 1.4T     | erigon-teku           |
| 1.2T     | nethermind-lodestar   |
| 1.1T     | nethermind-nimbus     |
| 1.1T     | nethermind-lighthouse |
| 1.1T     | nethermind-prysm      |
| 1.0T     | nethermind-teku       |
| 1.0T     | geth-lodestar         |
| 947G     | geth-lighthouse       |
| 946G     | geth-prysm            |
| 923G     | geth-nimbus           |
| 886G     | geth-teku             |
| 688G     | besu-lodestar         |
| 645G     | besu-prysm            |
| 604G     | besu-nimbus           |
| 631G     | besu-lighthouse       |
| 577G     | besu-teku             |

### Testnet Goerli

{% hint style="info" %}
Execution and consensus layer data usage numbers as of 2022.12.19 by Sea Monkey
{% endhint %}

| Disk Use | CL EL Combination     |
| -------- | --------------------- |
| 643G     | nimbus-erigon         |
| 639G     | lighthouse-erigon     |
| 431G     | lodestar-erigon       |
| 390G     | teku-erigon           |
| 344G     | lighthouse-nethermind |
| 330G     | prysm-nethermind      |
| 329G     | prysm-erigon          |
| 318G     | nimbus-nethermind     |
| 312G     | teku-nethermind       |
| 304G     | lighthouse-geth       |
| 288G     | lodestar-nethermind   |
| 281G     | nimbus-geth           |
| 273G     | lodestar-besu         |
| 270G     | teku-geth             |
| 268G     | lighthouse-besu       |
| 248G     | lodestar-geth         |
| 241G     | nimbus-besu           |
| 239G     | teku-besu             |
| 218G     | prysm-geth            |
| 142G     | prysm-besu            |


# Dealing with Storage Issues on the Execution Client

{% hint style="info" %}
It is currently recommended to use a minimum 1TB hard disk.

*Kudos to* [*angyts*](https://github.com/angyts) *for this contribution.*
{% endhint %}

After running the execution client for a while, you will notice that it will start to fill up the hard disk. The following steps might be helpful for you.

{% tabs %}
{% tab title="Manually Pruning Geth" %}
{% hint style="info" %}
Since Geth 1.10x version, the blockchain data can be regularly pruned to reduce it's size.
{% endhint %}

Reference: <https://gist.github.com/yorickdowne/3323759b4cbf2022e191ab058a4276b2>

You will need to upgrade Geth to at least 1.10x. Other prerequisites are a fully synced execution engine and that a snapshot has been created.

Stop your execution engine

```
sudo systemctl stop execution
```

Prune the blockchain data

```
sudo -u execution geth --datadir /var/lib/geth snapshot prune-state
```

{% hint style="warning" %}
:fire: **Geth pruning Caveats**:

* Pruning can take a few hours or longer (typically 2 to 10 hours is common) depending on your node's disk performance.
* There are three stages to pruning: **iterating state snapshot, pruning state data and compacting database.**
* "**Compacting database**" will stop updating status and appear hung. **Do not interrupt or restart this process.** Typically after an hour, pruning status messages will reappear.
  {% endhint %}

Restart execution engine

```
sudo systemctl start execution
```

{% endtab %}

{% tab title="Adding new hard disks and changing the data directory" %}
After you have installed your hard disk, you will need to properly format it and automount it. Consult the ubuntu guides on this.

I will assume that the new disk has been mounted onto `/mnt/`execution`-data`. (The name of the mount point is up to you)

Handling file permissions.

You need to change ownership of the folder to be accessible by your execution`service`. If your folder is a different name, please change the `/mnt/`execution`-data` accordingly.

```
sudo chown execution:execution /mnt/execution-data
```

```
sudo chmod 755 /mnt/execution-data
```

Stop your execution client.

```
sudo systemctl stop execution
```

Edit the system service file to point to a new data directory.

```
sudo nano /etc/systemd/system/execution.service
```

At the end of this command starting with `/usr/bin/geth --http --metrics ....` add a space and the following flag `--datadir "/mnt/`execution`-data"`.

`Ctrl-X` to save your settings.

Refresh the system service daemon to load the new configurations.

```
sudo systemctl daemon-reload
```

Restart the execution client.

```
sudo systemctl start execution
```

Make sure it is up and running by viewing the running logs.

```
sudo journalctl -fu execution
```

(**Optional**) Delete original data directory

```
sudo rm -r /var/lib/geth
```

{% endtab %}
{% endtabs %}


# Join the Community

## :mobile\_phone: Discord

* Lighthouse: <https://discord.com/invite/cyAszAh>
* Nimbus: <https://discord.com/invite/XRxWahP>
* Teku: <https://discord.com/invite/7hPv2T6>
* Prysm: <https://discord.com/invite/XkyZSSk4My>
* Lodestar: <https://discord.com/invite/aMxzVcr>
* Coincashew: <https://discord.gg/dEpAVWgFNB>

## :earth\_africa: Reddit r/ethStaker

* <https://www.reddit.com/r/ethstaker/>


# Credits

## :blush: Donation Tip Jar

{% hint style="info" %}
Did you find our guide useful? Let us know with a tip and we'll keep updating it. :pray: :rocket:

Use [cointr.ee to find our donation ](https://cointr.ee/coincashew)addresses or support us below at Gitcoin Grants. :pray:
{% endhint %}

Thank you for supporting Ethereum and us! Please use the below cointr.ee link. :blush:

{% embed url="<https://cointr.ee/coincashew>" %}

{% hint style="info" %}
:confetti\_ball: **Support us on Gitcoin Grants:** [We improve this guide with your support!](https://gitcoin.co/grants/1653/eth2-staking-guides-by-coincashew)🙏
{% endhint %}

## :grin: Thank You

Thanks to all 100,000+ of you, the ETH hodlers, buidlers, solo home stakers, and node operators for making the better future a reality.

Made by home stakers for the home staker community. Real open source.

Feedback or pull request contributions are much appreciated on [Github](https://github.com/coincashew/coincashew).

{% hint style="success" %}
These guides are proudly supported by Gitcoin Grants and Eth Stakers like yourself.
{% endhint %}

## :thumbsup: Last Words

> I stand upon the shoulders of giants and as such, invite you to stand upon mine. Use my work with or without attribution; I make no claim of "intellectual property." My ideas are the result of countless millenia of evolution - they belong to humanity.


# See Also

Soak in the following fountains of knowledge as you #StakeFromHome

## :jigsaw: Reference Material

Appreciate the hard work done by the fine folks at the following links which served as a foundation for creating this guide.

* **Official Ethereum Launchpad**: <https://launchpad.ethereum.org/en/>
* **Teku**: <https://docs.teku.pegasys.tech/en/latest/HowTo/Get-Started/Installation-Options/Build-From-Source/>
* **Lighthouse**: <https://lighthouse-book.sigmaprime.io/intro.html>
* **Nimbus**: <https://nimbus.guide/intro.html>
* **Prysm**: <https://docs.prylabs.network/docs/getting-started/>
* **Lodestar**: <https://chainsafe.github.io/lodestar/installation/>
* **Geth**: <https://geth.ethereum.org/docs>
* **Besu**: <https://besu.hyperledger.org/en/stable/>
* **Erigon**: <https://github.com/ledgerwatch/erigon#documentation>
* **Nethermind**: <https://docs.nethermind.io/nethermind/>

## :tada: Bonus links

### :bricks: Block Explorers

* [beaconcha.in](https://beaconcha.in/)
* [BeaconScan.com](https://beaconscan.com/)
* [BlockCypher.com](https://live.blockcypher.com/eth/)

### :record\_button: **Beacon Chain Stats**

* [Rated Network - Beacon Chain validator ratings](https://www.rated.network/)
* [Luckystaker.com - Calculate the probabilities of proposing a block](https://luckystaker.com)
* [beaconcha.in charts - Visualise the ethereum network](https://beaconcha.in/charts)

### :notepad\_spiral: Latest Eth Info

* **eth2New:** <https://hackmd.io/@benjaminion/eth2_news>
* **r/ETHstaker reddit:** <https://www.reddit.com/r/ethstaker>
* **Official Ethereum.org Blog:** [https://blog.ethereum.org/](https://blog.ethereum.org)

### :family\_mwgb: Additional ETH Staking Community Resources and Guides

* [Awesome Ethereum Staking Resources by armog](https://hackmd.io/@jyeAs_6oRjeDk2Mx5CZyBw/awesome-ethereum-staking)
* [Guide to Staking on Ethereum by Somer Esat](https://someresat.medium.com/)
* [Setup an Ethereum Mainnet Staking System with Prysm/Geth on Ubuntu by Metanull](https://github.com/metanull-operator/eth2-ubuntu)
* [ETH 2.0 Staking Guide: Prater || Lighthouse by agstakingco](https://agstakingco.gitbook.io/eth-2-0-staking-guide-prater-lighthouse/)
* [A slightly updated look at hardware for staking by u/LamboshiNakaghini](https://www.reddit.com/r/ethstaker/comments/j3mlup/a_slightly_updated_look_at_hardware_for_staking/)
* [How to stake for Ethereum 2.0 with DappNode by Raymond Durk](https://raymonddurk.medium.com/how-to-stake-for-ethereum-2-0-with-dappnode-231fa7689c02)
* [Ethereum Knowledge Base by beaconcha.in](https://kb.beaconcha.in/)
* [Ethereum on ARM](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/about-quick-start.html)

### :money\_mouth:MEV Info

* **Relay Overview:** <https://beaconcha.in/relays>
* **mevboost.org - Tracking relays and block builders**: [https://www.mevboost.org](https://www.mevboost.org/)
* **MEV Relays - Uptime Monitor:** [https://mev-relays.beaconstate.info](https://mev-relays.beaconstate.info/)
* **MEV Watch:** [https://www.mevwatch.info](https://www.mevwatch.info/)
* **MEV-Boost Dashboard:** [https://mevboost.pics](https://mevboost.pics/)
* **Tornado Warning:** [https://tornado-warning.info](https://tornado-warning.info/)
* **Rated Network Explorer:** <https://www.rated.network/relays?network=mainnet>
* **Metrica Relay Monitor:** <https://app.metrika.co/ethereum/dashboard/relay-monitor>
* **RelayScan.io MEV-Boost Analytics:** [https://www.relayscan.io](https://www.relayscan.io/)
* **MEV Relay List:** <https://www.coincashew.com/coins/overview-eth/mev-boost/mev-relay-list>
* **MEV-boost Setup Guide:** <https://www.coincashew.com/coins/overview-eth/mev-boost>


# Changelog

## :page\_facing\_up: List of changes

* Add downloadable [Lodestar](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-4-installing-consensus-client/lodestar) binaries as an installation option
* [Reth](/coins/overview-eth/testnet-holesky-validator/step-3-installing-execution-client/reth) Execution Client has reached V1.0 and is officially supported.
* New guide: [Recover ETH Validator Mnemonic Seed](/coins/overview-eth/guide-or-recover-ethereum-validator-mnemonic-seed)
* New [EthPillar](/coins/overview-eth/ethpillar) - a friendly TUI for node management! Command line use is greatly reduced. Update your software with a keystroke. Automatically install a minority client (Nethermind + Nimbus) node in minutes!
*

```
<figure><img src="/files/mjoXjfMBxYA0oP0f7OSM" alt=""><figcaption><p>ethpillar</p></figcaption></figure>
```

* Add Nimbus and Teku standalone beacon node/validator configurations
  * Useful for [rescuenode](https://rescuenode.com/docs/) failover setups or pointing a single validator client at multiple EL/CL nodes for extra redundancy and minimizing supermajority risks
* Added [Switching / Migration Execution Client guide](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/switching-execution-client) for both V2 and V1 staking setups
* Added [Reth Execution Client](/coins/overview-eth/testnet-holesky-validator/step-3-installing-execution-client/reth) - Alpha software, yet functional
* Created guide on how to [connect your wallet software to your own Node's RPC](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/using-staking-node-as-rpc-url-endpoint)
* Added [Holesky testnet staking guide](/coins/overview-eth/testnet-holesky-validator)
* Re-worked adding [new validator keys to existing setup](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/adding-a-new-validator-to-an-existing-setup).
* Added new Geth [how-to for enabling path based state storage](https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/geth-enabling-path-based-storage). Automated pruning!
* Staking setups prior to July 2023: V1 guides (using eth1 and beacon-chain, as systemd service names) can be accessed in the [archive section.](https://www.coincashew.com/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet)
* Major Version 2 Guides released!&#x20;
  * Notable changes include:
    * Dedicated service account users for execution / consensus / validator
    * Binaries deployed to /usr/local/bin
    * Data directory files stored in /var/lib
    * Options to download pre-built binaries or build from source
    * Simplified steps for full node non-staking users
    * Streamlined pre-requisites and node configuration steps
* Created guide for [How to re-sync using checkpoint sync](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/how-to-re-sync-using-checkpoint-sync)
* Created guide to [Updating 0x00 -> 0x01 Withdrawal keys with Ethdo for Shapella Upgrade](/coins/overview-eth/update-withdrawal-keys-for-ethereum-validator-bls-to-execution-change-or-0x00-to-0x01-with-ethdo)
* Added [disk usage numbers by EL CL combination](/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/disk-usage-by-execution-consensus-client)
* Include ETH Withdrawals address as default during validator key generation.
* Added [MEV-boost guide.](/coins/overview-eth/mev-boost)
* Updated to be mainnet merge ready.
* Are you ready for the Merge? [**Ethereum Merge Upgrade Checklist for Home Stakers and Validators**](https://www.coincashew.com/coins/overview-eth/ethereum-merge-upgrade-checklist-for-home-stakers-and-validators)
* Updated to use staking-deposit-cli
* \#TestingTheMerge on Ropsten: New Automated Install Script for the [Most Diverse Client: Besu+Lodestar](https://github.com/coincashew/ethereum-scripts/blob/main/README.md)
* Guides for Ropsten and [Kiln "Merge Testnets"](https://www.coincashew.com/coins/overview-eth/guide-or-besu-+-lodestar-or-most-viable-diverse-client-or-staking-ethereum-on-kiln-testnet)
* \#TestingTheMerge Guide on [Pithos Testnet](https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-for-ethereum-staking-on-pithos-testnet-in-10-minutes-or-less)
* Migration Guide with the goal of increasing ClientDiversity: [**Operation Client Diversity: Migrate Prysm to Teku**](https://www.coincashew.com/coins/overview-eth/guide-or-operation-client-diversity-migrate-prysm-to-teku)
* Updated besu execution client to use BONSAI format
* Restructured guide for improved speed and readability
* Added how to check your [Validator's Sync Committee duties](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance/checking-my-eth-validators-sync-committee-duties)
* Added new Formatting fixes and updated Teku initial state API.
* Updated with consensus layer (CL), the execution layer (EL), formerly known as eth2 and eth1.
* Added erigon build dependencies.
* Added Teku and Lodestar Checkpoint Sync feature, the quickest way to sync a Ethereum beacon chain client.
* geth + erigon pruning / Altair hard fork changes / nimbus eth1 fallback
* lighthouse + prysm doppelganger protection enabled. Doppelganger protection intentionally misses an epoch on startup and listens for attestations to make sure your keys are not still running on the old validator client.
* OpenEthereum will no longer be supported post London hard fork. Gnosis, maintainers of OpenEthereum, suggest users migrate to their new Erigon Ethererum client. Added setup instructions for **Erigon** under eth1 node section.
* Added [Mobile App Node Monitoring by beaconcha.in](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/mobile-app-node-monitoring-by-beaconchain)
* Updated staking-deposit-cli and added section on eth1 withdrawal address
* Added generating mnemonic seeds on **Tails OS** by [punggolzenith](https://github.com/punggolzenith)
* Iancoleman.io BLS12-381 Key Generation Tool [how-to added](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/eip2333-key-generator-by-iancoleman-io)
* Testnet guide forked for [Prater testnet](/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-testnet-prater-1) staking
* [Geth pruning guide](broken://pages/nYVvOTf1q4H6hPIMQusH) created
* Major changes to Lodestar guide
* Additional [Grafana Dashboards](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/monitoring-your-validator-with-grafana-and-prometheus) for Prysm, Lighthouse and Nimbus
* [Validator Security Best Practices added](broken://pages/Tb57gqyH5WWgWgjhdeME)
* Translations now available for Japanese, Chinese and Spanish (access by changing site language)
* Generate keystore files on [Ledger Nano X, Nano S and Trezor Model T](broken://pages/cN9iodUTjFprQfs3opkc) with tool from [allnodes.com](https://twitter.com/Allnodes/status/1390020240541618177?s=20)
* [Batch deposit tool](broken://pages/cN9iodUTjFprQfs3opkc) by [abyss.finance](https://twitter.com/AbyssFinance/status/1379732382044069888) now added


# Guide | How to setup a validator for Ethereum staking on testnet HOODI

Using the gold standard of ETH staking, become a solo home staker. Help decentralize Ethereum, a proof-of-stake blockchain. Anyone with 32 ETH can join.

{% hint style="danger" %}
DOCUMENTATION HAS MOVED TO > <https://docs.coincashew.com/guides/testnet-hoodi>

Below is for historical reference purposes only.
{% endhint %}

## :rocket:Option 1: Quickstart with EthPillar - Recommended for most users

### :arrow\_forward:  Ubuntu One-liner Install:

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

😄 **Friendly Node Installer**: Helps you deploy a systemd installation with minority clients Nimbus-Nethermind or Teku-Besu stack in just minutes. MEVboost included. Lido CSM supported.

:floppy\_disk: **Ease of use**: No more remembering CLI commands required. Access common node operations via a simple text user interface (TUI). When EthPillar is deployed, operating your node becomes a breeze.

:owl: **Fast Updates**: Quickly find and download the latest consensus/execution release. Less downtime!

#### :exclamation:To learn more about EthPillar, [visit the quickstart page.](/coins/overview-eth/ethpillar)

<figure><img src="/files/HCFPqea9Z5MktcDDPTvQ" alt=""><figcaption><p>EthPillar's TUI - Navigate the menu to control your node</p></figcaption></figure>

## :chains:Option 2: Manual Installation

* This guide aims to reduce the reliance on scripts in this section to make the learning process more straightforward and understandable.
* This approach provides a detailed overview of the steps involved, ensuring stakers have a clear understanding of the process.
* Great for advanced users comfortable with the CLI terminal who want full control and require customization of EL/CL combinations and their configurations.
* Deploys a systemd installation with any EL/CL combination you choose.
* After installation, use [EthPillar](/coins/overview-eth/ethpillar) to simplify maintenance of your node.

To install manually, continue with this guide.

#### :shield: Built by home-stakers for home-stakers. :pray:


# Overview - Manual Installation

## :new: Announcements

{% hint style="success" %}
As of March 17 2024, this **Version 2 Guide** written for **🦉Dencun**🦉 **Hoodi Testnet** :grin:
{% endhint %}

{% hint style="info" %}
:sparkles:**Always test and practice on testnet first.** [**Mainnet guide available here.**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet)
{% endhint %}

## :wrench: About This Guide

For the advanced user who wants customization and is comfortable with CLI commands, this guide will walk you through the details of setting up a validator. For most users, the quickest and automated way to setup a staking node is with [EthPillar](/coins/overview-eth/ethpillar).

## :thumbsup: Your Github Contributions Welcome

This guide is fully open source and fully powered by home-stakers like you.

Pull requests or issues can be submitted on [github](https://github.com/coincashew/coincashew).

{% embed url="<https://github.com/coincashew/coincashew>" %}

#### :arrow\_up: [View Changelog](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/changelog): See the latest changes to the guide.


# Step 1: Prerequisites

## :rocket: How Staking on Ethereum Works

1. Acquire some hardware (laptop, desktop, server) or rent a VPS (cloud server): You need to run a node to stake.
2. Sync an execution layer client
3. Sync a consensus layer client
4. Generate your validator keys and import them into your validator client
5. Monitor and maintain your node

A Ethereum node consists of the Execution Layer + Consensus Layer.

A Ethereum Staking node is the previous plus a Validator client.

<figure><img src="/files/s1oKZXCcrZioRrPAMkps" alt=""><figcaption><p>Client Stack</p></figcaption></figure>

<figure><img src="/files/gY9TruKmwgL2Jn9yFe1U" alt=""><figcaption><p>Big picture: Execution / Consensus / Validator</p></figcaption></figure>

## :wave: Introduction

This guide was written for aspiring Ethereum stakers who have basic familiarity with command line tools and it was tested against Ubuntu LTS client. You’ll want a dedicated cloud VPS or local desktop/server/laptop running a clean install of Ubuntu preferably.

### Terminology

Your Ethereum staking node may be

* **Local:** on a laptop / PC / NUC that you can physically connect keyboard/mouse/monitor.
* **Remote:** in the cloud on a VPS

If your staking node is **remote**, then you will want to setup SSH, secure shell.

If using a VPS or **remote** node, install and start the SSH client for your operating system:

**Windows**: [PuTTY](https://www.puttygen.com/download-putty)

**MacOS and Linux**: from the Terminal, use the native command:

```
ssh <YourUserName>@<YourServersIP>
```

Here's a [guide from Makeuseof](https://www.makeuseof.com/tag/beginners-guide-setting-ssh-linux-testing-setup/) to connect by SSH to your **remote node.**

## :hammer\_pick: How to Run Commands

* Commands are to be run in a terminal window or ssh terminal.
* Commands preceded by `sudo` will prompt for your password at first, and periodically afterwards.

## :woman\_technologist: Skills for operating an staking node

As a validator for Ethereum, you will typically have the following abilities:

* operational knowledge of how to set up, run and maintain a Ethereum consensus client, execution client and validator continuously
* a long term commitment to maintain your validator 24/7/365
* basic operating system skills

## :man\_technologist: Experience required to be a successful ETH Staker

* have studied [Ethstaker's Staking for Beginners](https://www.reddit.com/r/ethstaker/wiki/staking_for_beginners/)
* have perused the vast tomes of the [EthStaker Knowledge Base](https://docs.ethstaker.cc/ethstaker-knowledge-base/)

## :man\_lifting\_weights: Recommended Node Setup Requirements

* **Operating system:** Ubuntu LTS Server or Desktop
* **Processor:** 4 CPU Cores or more
* **Memory:** 32GB RAM
* **Storage:** Testnet: 300GB. Mainnet: 4TB NVME (not QLC).
* **Internet:** Stable broadband internet connections with speeds at least 20 Mbps without data limit.
* **Data Plan**: At least 2 TB per month. Ideally, no data cap or unlimited data plan.
* **Power:** Reliable electrical power with a [Uninterruptible Power Supply (UPS)](https://www.lifewire.com/best-uninterrupted-power-supplies-4142625).
* **ETH balance:** 2.4ETH for [Lido CSM](https://csm.testnet.fi/?ref=ethpillar) or at least 32 ETH for solo staking with 1 validator
* **Wallet**: [Rabby](https://rabby.io/) Wallet installed

{% hint style="info" %}
:desktop: **Hardware Builds**: For examples of actual staking hardware builds, check out [RocketPool's hardware guide](https://github.com/rocket-pool/docs.rocketpool.net/blob/main/docs/guides/node/local/hardware.md#example-setups) and [Ethstaker's Hardware Examples](https://docs.ethstaker.cc/ethstaker-knowledge-base/hardware/hardware-examples).
{% endhint %}

{% hint style="info" %}
:cd: **Storage Suggestion**: Check out the following to find your ideal NVME or SSD drive.

* [**Yorick's Storage Advice**](https://gist.github.com/yorickdowne/f3a3e79a573bf35767cd002cc977b038): Refer to Yorick's Great and less great SSDs for Ethereum nodes
* [**Top SSD List**](https://docs.google.com/spreadsheets/d/1B27_j9NDPU3cNlj2HKcrfpJKHkOf-Oi1DbuuQva2gT4/edit)**:** Suitable drives are identified as Mid-Range or better.
  {% endhint %}

<figure><img src="/files/X2z463D8wsbAfaAYxeJg" alt=""><figcaption><p>Ethereum Staking Node</p></figcaption></figure>

{% hint style="success" %}
:sparkles: **Pro Validator Tip**: Highly recommend you begin with a brand new instance of an OS, VM, and/or machine. Avoid headaches by NOT reusing testnet keys, wallets, or databases for your validator.
{% endhint %}

## :desktop: Local Node vs Remote Node

**Decision**: Do I run my Ethereum staking node locally at home or rent a VPS cloud server remotely? Here's a list of criteria to help you decide.

|       Criteria       | Local Node                                                                                                                                         | Remote Node                                                                                                                                                                 |
| :------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|     Ongoing Costs    | Plus - No fees, besides internet bill and electricity.                                                                                             | Minus - Monthly or Annual reoccurring rental fees.                                                                                                                          |
| Hardware Maintenance | Minus - Do it yourself if hardware issues.                                                                                                         | Plus - Included, covered by hosting provider.                                                                                                                               |
|       Internet       | Minus - Can slow down home internet and use up data plan (if not unlimited) Budget for at least 2TB per month data plan.                           | Plus - Often plans are generous and more than sufficient for an ETH node.                                                                                                   |
|      Reliability     | Minus - Do it yourself with UPS, redundant internet connections, computer issues                                                                   | Plus - Hosted in a data center with multiple power/internet backups.                                                                                                        |
|   Barrier to Entry   | <p>Plus - Can re-use or re-purpose existing hardware<br><br>Minus - Initial cost to purchase new computer equipment</p>                            | Plus - Renting a VPS might require a lower initial investment as you can pay monthly.                                                                                       |
|   Decentralization   | Plus - Home staking is the **gold standard** for Ethereum decentralization, nothing bets it!                                                       | Minus - VPS cloud hosts like [Netcup](https://www.netcup.eu/bestellen/produkt.php?produkt=3026) or AmazonWebServices are by nature more centralized.                        |
|     Customization    | Plus - More fine control over hardware configuration                                                                                               | Minus - May be limited choices and hardware can be shared. For example, a common issue is insufficient disk storage I/O speeds (IOPS).                                      |
|       Security       | Plus - As secure as your home and personal [OPSEC](https://en.wikipedia.org/wiki/Operations_security)                                              | <p>Plus - Enterprise-grade, professional data centers.</p><p>Minus - Not your hardware, not your node. It's possible the hosting provide can view your node's contents.</p> |
|        Freedom       | <p>Plus - Do whatever you want. Plan your own upgrades.<br><br>Minus - With great freedom and power, you are solely responsible for your node.</p> | <p>Plus - Professionally managed.</p><p><br>Minus - At the mercy of the host's actions, data center outages are possible.</p>                                               |

## :tools: Setup Ubuntu

With your local or remote node, now you need to install an Operating System. This guide is designed for Ubuntu LTS.

* To install **Ubuntu Server or Desktop**, refer to this [guide](https://docs.ethstaker.cc/ethstaker-knowledge-base/tutorials/installing-linux).

{% hint style="info" %}
**Recommendation**: A headless (no monitor) install of **Ubuntu Server** on a **dedicated** NUC/laptop/desktop/VPS is best for ease of reliability and security. :fire: Do not use this system for email/browsing web/gaming/socials. :fire:
{% endhint %}

{% hint style="warning" %}
**Tip**: When installing Ubuntu Server, ensure you are selecting “**Use an entire disk**” on the **Guided storage configuration** screen. Next screen will be the **Storage configuration** screen, ensure your settings are using all available disk storage. A [common issue](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/using-all-available-lvm-disk-space) is that Ubuntu server defaults to using only 200GB.
{% endhint %}

## :performing\_arts: Setup Rabby

When the time comes to make your validator's 32ETH deposit(s), you'll need a wallet to transfer funds to the beacon chain deposit contract.

* To install Rabby, visit their [official site.](https://rabby.io/)

## :jigsaw: High Level Validator Node Overview

{% hint style="info" %}
At the end of this guide, you will build a staking validator node that hosts three main components in two layers: consensus layer consists of a consensus client, also known as a validator client with a beacon chain client. The execution layer consists of a execution client, formerly a eth1 node.

**Validator client** - Responsible for producing new blocks and attestations in the beacon chain and shard chains.

**Consensus client** - Responsible for managing the state of the beacon chain, validator shuffling, and more.

**Execution client** - Supplies incoming validator deposits from the eth mainnet chain to the beacon chain client.
{% endhint %}

![How Ethereum nodes fits together featuring Leslie the Rhino, the mascot named after American computer scientist Leslie Lamport](/files/-MPCDQuE1PFqzrv0AzuT)


# Step 2: Configuring Node

## :hammer\_pick: Node Configuration

### Logging to the node

**Using Ubuntu Server**: Begin by connecting with your SSH client.

```bash
ssh username@staking.node.ip.address
```

**Using Ubuntu Desktop**: You're likely in-front of your **local** node. Simply open a terminal window from anywhere by typing Ctrl+Alt+T.

### Updating the node

Ensure all the latest packages, tools and patches are installed first, then reboot.

```bash
sudo apt-get update -y && sudo apt dist-upgrade -y
sudo apt-get install git ufw curl ccze jq -y
sudo apt-get autoremove
sudo apt-get autoclean
sudo reboot
```

## :key: Security Configuration

### Create a non-root user with sudo privileges

<details>

<summary>Creating a user called ethereum</summary>

Create a new user called `ethereum`

```bash
sudo useradd -m -s /bin/bash ethereum
```

Set the password for ethereum user

```bash
sudo passwd ethereum
```

Add ethereum to the sudo group

```bash
sudo usermod -aG sudo ethereum
```

Log out and log back in as this new user.

**Using Ubuntu Server**: Use the following commands.

```bash
exit
ssh ethereum@staking.node.ip.address
```

**Using Ubuntu Desktop**: Log out can be found in the top right corner under the Power Icon. Click the `ethereum` user account and enter password.

</details>

{% hint style="warning" %}
:fire:**Important reminder**: Ensure you are logged in and execute all steps in this guide as this non-root user, `ethereum`.
{% endhint %}

### Hardening SSH Access

{% hint style="info" %}
**Local node**? You can skip this section on Hardening SSH Access.
{% endhint %}

<details>

<summary>Creating a new SSH Key</summary>

Create a new SSH key pair on **your client machine (i.e. local laptop)**. Run this on **your client machine,** not remote node. Update the comment with your email or a comment.

```
ssh-keygen -t ed25519 -C "name@email.com"
```

You'll see this next:

```
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/<myUserName>/.ssh/id_ed25519):
```

Here you're asked to type a file name in which to save the SSH private key. If you press enter, you can use the default file name `id_ed25519`

Next, you're prompted to enter a passphrase.

```
Enter passphrase (empty for no passphrase):
```

:information\_source: A **passphrase** adds an extra layer of protection to your SSH private key. Everytime you connect via SSH to your remote node, enter this passphrase to unlock your SSH private key.

:fire: Passphrase is highly recommended! Do not leave this empty for no passphrase.

:bulb:Do not forget or lose your passphrase. Save this to a password manager.

**Location**: Your SSH key pair is stored in your home directory under `~/.ssh`

**File name:** If your default keyname is`id_ed25519`, then

* your **private SSH key** is `id_ed25519`
* your **public SSH key** is `id_ed25519.pub`

:fire: **IMPORTANT:** Make multiple backup copies of your **private SSH key file** to external storage, such as a USB backup key, for recovery purposes. Also backup your **passphrase**!

Verify the contents of your private SSH key file before moving on.

```
cat ~/.ssh/id_ed25519
```

It should look similar to this example.

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBAblzWLb7/0o62FZf9YjLPCV4qFhbqiSH3TBvZXBiYNgAAAJCWunkulrp5
LgAAAAtzc2gtZWQyNTUxOQAAACBAblzWLb7/0o62FZf9YjLPCV4qFhbqiSH3TBvZXBiYNg
AAAEAxT+yCmifGWgbFnkauf0HyOAJANhYY5EElEX8fI+M4B0BuXNYtvv/SjrYVl/1iMs8J
XioWFuqJIfdMG9lcGJg2AAAACWV0aDJAZXRoMgECAwQ=
-----END OPENSSH PRIVATE KEY-----
```

</details>

#### Transferring the SSH Public Key to Remote node

<details>

<summary>Option 1: Transferring with ssh-copy-id</summary>

Works with Linux or MacOS. Use option 2 for Windows.

```bash
ssh-copy-id -i ~/.ssh/id_ed25519 ethereum@staking.node.ip.address
```

</details>

<details>

<summary>Option 2: Copying the key manually</summary>

First, begin by obtaining your SSH Public key.

For Linux/Mac,

```
cat ~/.ssh/id_ed25519.pub
```

For Windows,

Open a command prompt (Windows Key + R, then `cmd`, finally press enter).

```
type %USERPROFILE%\.ssh\id_ed25519.pub
```

The output will look similar to the following:

```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAoc78lv+XDh2znunKXUF/9zBNJrM4Nh67yut9RN14SX name@email.com
```

Copy into your clipboard this output, also known as your public SSH key.

On your **remote node**, run the following:

```
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys
```

First, a directory called **.ssh** is created, then `Nano` is a text editor for editing a special file called **authorized\_keys**

With nano opening the authorized\_keys file, right-click your mouse to paste your public SSH key into this file.

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

Verify your public SSH key was properly pasted into the file.

```
cat ~/.ssh/authorized_keys
```

</details>

#### Disabling Password Authentication

<details>

<summary>Disabling root login and password based login</summary>

:information\_source: With SSH key authentication enabled, there's still the possibility to connect to your remote node with login and password, a much less secure and brute force-able attack vector.

Login via ssh with your new ethereum user

```
ssh ethereum@staking.node.ip.address
```

Edit the ssh configuration file

```
sudo nano /etc/ssh/sshd_config
```

Locate **PubkeyAuthentication** and update to yes. Delete the # in front.

```
PubkeyAuthentication yes
```

Locate **PasswordAuthentication** and update to no. Delete the # in front.

```
PasswordAuthentication no
```

Locate **PermitRootLogin** and update to prohibit-password. Delete the # in front.

```
PermitRootLogin prohibit-password
```

Locate **PermitEmptyPasswords** and update to no. Delete the # in front.

```
PermitEmptyPassword no
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

Validate the syntax of your new SSH configuration.

```
sudo sshd -t
```

If no errors with the syntax validation, restart the SSH process.

```
sudo systemctl restart sshd
```

Verify the login still works.

```
ssh ethereum@staking.node.ip.address
```

**Optional**: Make logging in easier by updating your local ssh config.

To simplify the ssh command needed to log in to your server, consider updating on your local client machine the `$HOME/myUserName/.ssh/config` file:

```bash
Host ethereum-server
  User ethereum
  HostName <staking.node.ip.address>
  Port 22
```

This will allow you to log in with `ssh ethereum-server` rather than needing to pass through all ssh parameters explicitly.

</details>

### Synchronizing time with Chrony

chrony is an implementation of the Network Time Protocol and helps to keep your computer's time synchronized with NTP.

{% hint style="info" %}
Because the consensus client relies on accurate times to perform attestations and produce blocks, your node's time must be accurate to real NTP time within 0.5 seconds.
{% endhint %}

To install chrony:

```bash
sudo apt-get install chrony -y
```

To see the source of synchronization data.

```
chronyc sources
```

To view the current status of chrony.

```
chronyc tracking
```

### Setting Timezone

To pick your timezone run the following command:

```bash
sudo dpkg-reconfigure tzdata
```

Find your region using the simple text-based GUI.

In the event that you are using national system like India's `IST` select:

```
Asia/Kolkata
```

This will be appropriate for all locales in the country (`IST`, `GMT+0530`).

### Creating the jwtsecret file

A jwtsecret file contains a hexadecimal string that is passed to both Execution Layer client and Consensus Layer clients, and is used to ensure authenticated communications between both clients.

```bash
#store the jwtsecret file at /secrets
sudo mkdir -p /secrets

#create the jwtsecret file
openssl rand -hex 32 | tr -d "\n" | sudo tee /secrets/jwtsecret

#enable read access
sudo chmod 644 /secrets/jwtsecret
```

## :link: Network Configuration

The standard UFW - Uncomplicated firewall can be used to control network access to your node and protect against unwelcome intruders.

### Configure UFW Defaults

By default, deny all incoming traffic and allow outgoing traffic.

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Configure SSH Port 22

If your node is remote in the cloud, or at home but on a different headless server, you will need to enable SSH port 22 in order to connect.

```bash
# Allow ssh access for remote node
sudo ufw allow 22/tcp comment 'Allow SSH port'
```

If your node is local at home and you have **keyboard access** to it, it's good practice to deny SSH port 22.

```bash
# Deny ssh access for local node
sudo ufw deny 22/tcp comment 'Deny SSH port'
```

### Allow Execution Client Port 30303

Peering on port 30303, execution clients use this port for communication with other network peers.

```bash
sudo ufw allow 30303 comment 'Allow execution client port'
```

### Allow Consensus Client port

Consensus clients generally use port 9000 for communication with other network peers. Using tcp port 13000 and udp port 12000, Prysm uses a slightly different configuration.

```bash
# Lighthouse, Lodestar, Nimbus, Teku
sudo ufw allow 9000 comment 'Allow consensus client port'

# Lighthouse Quic Port https://lighthouse-blog.sigmaprime.io/Quic.html
sudo ufw allow 9001/udp comment 'Allow lighthouse client quic port'

# Prysm
sudo ufw allow 13000/tcp comment 'Allow consensus client port'
sudo ufw allow 12000/udp comment 'Allow consensus client port'
```

### Enable firewall

Finally, enable the firewall and review the configuration.

```bash
sudo ufw enable
sudo ufw status numbered 
```

Example of ufw status for a remote staking node configured for Prysm consensus client.

> ```csharp
>      To                         Action      From
>      --                         ------      ----
> [ 1] 22/tcp                     ALLOW IN    Anywhere
> [ 2] 9000                       ALLOW IN    Anywhere
> [ 3] 30303                      ALLOW IN    Anywhere
> [ 4] 22/tcp (v6)                ALLOW IN    Anywhere (v6)
> [ 5] 9000 (v6)                  ALLOW IN    Anywhere (v6)
> [ 6] 30303 (v6)                 ALLOW IN    Anywhere (v6)
> ```

### Configure Port Forwarding

**Port Forwarding Tip for Local Stakers at Home:** You'll need to forward ports to your validator.

For optimal connectivity, ensure Port Forwarding is setup for your router. Learn to port forward with guides found at [https://portforward.com/how-to-port-forward](https://portforward.com/how-to-port-forward/)

Verify port forwarding is working with the following.

**Option 1:** From the terminal on staking machine. Choose accordingly to your clients.

```bash
# Lighthouse, Lodestar, Nimbus, Teku
curl https://eth2-client-port-checker.vercel.app/api/checker?ports=30303,9000

# Prysm
curl https://eth2-client-port-checker.vercel.app/api/checker?ports=30303,12000,13000
```

**Result:** Open ports will be shown if reachable from public.

\
**Option 2:** Using the browser

* <https://www.yougetsignal.com/tools/open-ports/>
* or <https://canyouseeme.org>

As an example, for Lighthouse, you would verify ports 9000 and 30303 are reachable.

### Optional: Whitelisting Connections

Whitelisting, which means permitting connections from a specific IP, can be setup via the following command.

```bash
sudo ufw allow from <your client machine>
# Example
# sudo ufw allow from 192.168.50.22
```

### :chains: **Install Fail2ban**

{% hint style="info" %}
Fail2ban is an intrusion-prevention system that monitors log files and searches for particular patterns that correspond to a failed login attempt. If a certain number of failed logins are detected from a specific IP address (within a specified amount of time), fail2ban blocks access from that IP address.
{% endhint %}

To install fail2ban:

```bash
sudo apt-get install fail2ban -y
```

Edit a config file that monitors SSH logins.

```bash
sudo nano /etc/fail2ban/jail.local
```

Add the following lines to the bottom of the file.

```bash
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
```

To exit and save, press `Ctrl` + `X`, then `Y`, then`Enter`.

Restart fail2ban for settings to take effect.

```bash
sudo systemctl restart fail2ban
```


# Step 3: Installing execution client

Your choice of either [**Besu**](https://besu.hyperledger.org)**,** [**Nethermind**](https://www.nethermind.io)**, Geth,** [**Reth**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/step-3-installing-execution-client/reth) **or** [**Erigon**](https://github.com/ledgerwatch/erigon)**.**

{% hint style="warning" %}
Only one execution client is required per node.
{% endhint %}

## **Execution Client Diversity**

* To strengthen Ethereum's resilience against potential attacks or consensus bugs, it's best practice to run a minority client in order to increase client diversity.
* Find the latest distribution of execution clients here: [https://clientdiversity.org](https://clientdiversity.org/)

<figure><img src="/files/0OnebPfVnFfirmtThJAt" alt=""><figcaption><p>EL Diversity as of Dec 2024</p></figcaption></figure>

## Overview of Execution Clients

{% hint style="info" %}
:shield: **Recommendation** :shield:: **Nethermind** or **Besu**
{% endhint %}

### Nethermind

* Nethermind: Open-source Ethereum client written in .NET Core.
* Fast sync speed: Boasts the quickest Execution client syncing performance and is designed so you can start following the chain and attesting while it downloads history in the background.
* Flexible configuration: Rich set of options tailored for node operators.
* Online pruning: Allows database pruning while still online, no need to turn off client.
* Resource-intensive pruning process: May result in noticeable performance degradation for low-power nodes during the process.

### Besu

* Hyperledger Besu: Open-source Ethereum client under Apache 2.0 license, written in Java.
* Distinctive features: Uses Bonsai Tries for state storage for enhanced performance and benefits.
* Maintenance-free: Does not require pruning, making it effectively maintenance-free.

### Geth

* Geth (Go Ethereum): One of the original Ethereum protocol implementations, written in Go and fully open source under GNU LGPL v3 license.
* Stable and reliable: Oldest and most widely-used Execution Client with a strong reputation.
* Multithreaded: Utilizes the entire CPU for enhanced performance.
* Adjustable RAM usage: Configurable down to 4 GB minimum for Mainnet, accommodating various system specifications.

### Erigon

* Erigon: High-performance Ethereum implementation focused on efficiency, faster synchronization, and optimized experience written in Go.
* Born as a Geth fork, completely rewritten for enhanced speed and storage savings.
* Faster archive node synchronization: Achieves full node synchronization in under three days with less than 2TB of storage.
* Supports several popular EVM-compatible blockchains and testnets.
* Efficient state storage: Utilizes a key-value database for improved performance.
* Separate JSON RPC daemon: Enables read-only calls without requiring the same system as the main Erigon binary, even from a database snapshot.

### Reth

* Reth: Execution layer (EL) Ethereum client, written in Rust, is compatible with all consensus layer (CL) implementations.
* Developed by Paradigm, licensed under Apache and MIT licenses.
* Capabilities: Sending/receiving transactions, querying logs and traces, and accessing/interacting with smart contracts.
* Prioritizing security, efficiency, and ease-of-use for consumer hardware.

## Comparison of Execution Clients

<table><thead><tr><th>Client</th><th width="111">RAM Use</th><th>Minimum Database Size</th><th>Database Growth</th><th>Time to sync</th></tr></thead><tbody><tr><td><strong>Nethermind</strong></td><td>8 GB</td><td>0.95 TB</td><td>18 GB/week</td><td>Fastest, 2hrs+</td></tr><tr><td><strong>Besu</strong></td><td>12 GB</td><td>1.2 TB</td><td>10 GB/week</td><td>Medium, 16hrs+</td></tr><tr><td><strong>Geth</strong></td><td>8 GB</td><td>1.2 TB</td><td>8 GB/week</td><td>Fast, 8hrs+</td></tr><tr><td><strong>Erigon 3</strong></td><td>8 GB</td><td>0.92 GB</td><td>8 GB/week</td><td>Medium, 16hrs+</td></tr><tr><td><strong>Reth</strong></td><td>10 GB</td><td>1.2 TB</td><td>4GB/week</td><td>Medium, 16hrs+</td></tr></tbody></table>

#### Notes:

* Time to sync to a state capable beginning attestations depends on the IOPs of your storage drive.
* Initial sync is always resource intensive. Synced operation is relatively resource use light.
* Nethermind, Besu, Geth have the capability to prune the database.


# Nethermind

## Overview

{% hint style="info" %}
**Nethermind** is a flagship Ethereum client all about performance and flexibility. Built on **.NET** core, a widespread, enterprise-friendly platform, Nethermind makes integration with existing infrastructures simple, without losing sight of stability, reliability, data integrity, and security.
{% endhint %}

#### Official Links

| Subject       | Link                                                                                |
| ------------- | ----------------------------------------------------------------------------------- |
| Releases      | <https://github.com/NethermindEth/nethermind/releases>                              |
| Documentation | [https://docs.nethermind.io](https://docs.nethermind.io/)                           |
| Website       | [https://nethermind.io/nethermind-client](https://nethermind.io/nethermind-client/) |

### 1. Initial configuration

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/nethermind
sudo chown -R execution:execution /var/lib/nethermind
```

Install dependencies.

```bash
sudo apt update
sudo apt install ccze curl libsnappy-dev libc6-dev jq libc6 unzip -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-zip and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/NethermindEth/nethermind/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-x64)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O nethermind.zip $BINARIES_URL
unzip -o nethermind.zip -d $HOME/nethermind
rm nethermind.zip
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/nethermind /usr/local/bin/nethermind
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install .NET SDK build dependencies.

```bash
#Get latest .net sdk
curl -L https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
chmod +x ./dotnet-install.sh
./dotnet-install.sh --channel 9.0 --runtime aspnetcore
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
# Clone the repo
git clone https://github.com/NethermindEth/nethermind.git
cd nethermind
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
dotnet publish src/Nethermind/Nethermind.Runner -c release -o nethermind
```

Verify Nethermind was properly built by checking the version.

```shell
./nethermind/nethermind --version
```

Sample output of a compatible version.

```
Version: 1.25.2+78c7bf5f
Commit: 78c7bf5f2c0819f23e248ee6d108c17cd053ffd3
Build Date: 2024-01-23 06:34:53Z
OS: Linux x64
Runtime: .NET 8.0.1
```

Install the binaries.

<pre class="language-shell"><code class="lang-shell"><strong>sudo mv $HOME/git/nethermind/nethermind /usr/local/bin
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Nethermind Execution Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=always
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
WorkingDirectory=/var/lib/nethermind
Environment="DOTNET_BUNDLE_EXTRACT_BASE_DIR=/var/lib/nethermind"
ExecStart=/usr/local/bin/nethermind/nethermind \
  --config hoodi \
  --datadir="/var/lib/nethermind" \
  --Network.DiscoveryPort 30303 \
  --Network.P2PPort 30303 \
  --Network.MaxActivePeers 50 \
  --JsonRpc.Port 8545 \
  --JsonRpc.EnginePort 8551 \
  --Metrics.Enabled true \
  --Metrics.ExposePort 6060 \
  --JsonRpc.JwtSecretFile /secrets/jwtsecret \
  --Pruning.Mode=Hybrid \
  --Pruning.FullPruningTrigger=VolumeFreeSpace \
  --Pruning.FullPruningThresholdMb=375810 \
  --Pruning.FullPruningMemoryBudgetMb=16384 \
  --Pruning.FullPruningMaxDegreeOfParallelism=2 \
  --Pruning.FullPruningCompletionBehavior=AlwaysShutdown
   
[Install]
WantedBy=multi-user.target
```

{% hint style="info" %}
Nethermind will prune the database when disk space is low (below 300GB)
{% endhint %}

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu execution | ccze
```

A properly functioning **Nethermind** execution client will indicate "Received new block". For example,

```
Nethermind.Runner[2]: 29 Sep 03:00:00 | Received new block:  8372 (0x425ab9...854f4)
Nethermind.Runner[2]: 29 Sep 03:00:00 | Processed                8372     |      0.17 ms  |  slot     13,001 ms |
Nethermind.Runner[2]: 29 Sep 03:00:00 | - Block               0.00 MGas   |      0    txs |  calls      0 (  0) | sload       0 | sstore      0 | create   0
Nethermind.Runner[2]: 29 Sep 03:00:00 | - Block throughput    0.00 MGas/s |      0.00 t/s |       7217.16 Blk/s | recv        0 | proc        0
Nethermind.Runner[2]: 29 Sep 03:00:00 | Received ForkChoice: Head: 8372 (0x425ab9...854f4), Safe: 8350 (0xfd781...c2e19f), Finalized: 8332 (0x9ccf...88684c)
Nethermind.Runner[2]: 29 Sep 03:00:00 | Synced chain Head to 8372 (0x425ab9...2881a5)
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/nethermind/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Besu

## Overview

{% hint style="info" %}
**Hyperledger Besu** is an open-source Ethereum client designed for demanding enterprise applications requiring secure, high-performance transaction processing in a private network. It's developed under the Apache 2.0 license and written in **Java**.
{% endhint %}

#### Official Links

| Subject       | Link                                                                    |
| ------------- | ----------------------------------------------------------------------- |
| Releases      | <https://github.com/hyperledger/besu/releases>                          |
| Documentation | [https://besu.hyperledger.org](https://besu.hyperledger.org/en/stable/) |
| Website       | <https://www.hyperledger.org/use/besu>                                  |

### 1. Initial configuration

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/besu
sudo chown -R execution:execution /var/lib/besu
```

Install dependencies.

```bash
sudo apt install -y openjdk-21-jdk libjemalloc-dev jq
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/hyperledger/besu/releases/latest"
TAG=$(curl -s $RELEASE_URL | jq -r .tag_name)
BINARIES_URL="https://github.com/hyperledger/besu/releases/download/$TAG/besu-$TAG.tar.gz"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O besu.tar.gz $BINARIES_URL
tar -xzvf besu.tar.gz -C $HOME
rm besu.tar.gz
sudo mv $HOME/besu-${TAG} besu
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/besu /usr/local/bin/besu
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
# Clone the repo
git clone https://github.com/hyperledger/besu.git
cd besu
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
./gradlew installDist
```

Verify Besu was properly built by checking the version.

```shell
./build/install/besu/bin/besu --version
```

Sample output of a compatible version.

```
besu/v23.4.0/linux-x86_64/openjdk-java-17
```

Install the binaries.

<pre class="language-shell"><code class="lang-shell"><strong>sudo cp -a $HOME/git/besu/build/install/besu /usr/local/bin/besu
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Besu Execution Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment="JAVA_OPTS=-Xmx5g"
ExecStart=/usr/local/bin/besu/bin/besu \
  --network=hoodi \
  --p2p-port=30303 \
  --rpc-http-port=8545 \
  --engine-rpc-port=8551 \
  --max-peers=25 \
  --metrics-enabled=true \
  --metrics-port=6060 \
  --rpc-http-enabled=true \
  --sync-mode=SNAP \
  --data-storage-format=BONSAI \
  --data-path="/var/lib/besu" \
  --engine-jwt-secret=/secrets/jwtsecret
  
[Install]
WantedBy=multi-user.target
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu execution | ccze
```

A properly functioning **Besu** execution client will indicate "Fork-Choice-Updates". For example,

```
2022-03-19 04:09:36.315+00:00 | vert.x-worker-thread-0 | INFO  | EngineForkchoiceUpdated | Consensus fork-choice-update: head: 0xcd2a_8b32..., finalized: 0xfa22_1142...
2022-03-19 04:09:48.328+00:00 | vert.x-worker-thread-0 | INFO  | EngineForkchoiceUpdated | Consensus fork-choice-update: head: 0xff1a_f12a..., finalized: 0xfa22_1142...
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/besu/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Geth

## Overview

{% hint style="danger" %}
:octagonal\_sign:**Strongly discouraged** :octagonal\_sign:**: GETH can be** [**hazardous to your all YOUR STAKE.**](https://twitter.com/EthDreamer/status/1749355402473410714)

Select a minority client.&#x20;

**Recommendation:** Besu or Nethermind.
{% endhint %}

{% hint style="info" %}
**Geth** - Go Ethereum is one of the three original implementations (along with C++ and Python) of the Ethereum protocol. It is written in **Go**, fully open source and licensed under the GNU LGPL v3.
{% endhint %}

#### Official Links

| Subject       | Link                                                    |
| ------------- | ------------------------------------------------------- |
| Releases      | <https://github.com/ethereum/go-ethereum/releases>      |
| Documentation | <https://geth.ethereum.org/docs>                        |
| Website       | [https://geth.ethereum.org](https://geth.ethereum.org/) |

### 1. Create service account and data directory

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/geth
sudo chown -R execution:execution /var/lib/geth
```

### **2. Install binaries**

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

<pre class="language-bash"><code class="lang-bash">RELEASE_URL="https://geth.ethereum.org/downloads"
<strong>FILE="https://gethstore.blob.core.windows.net/builds/geth-linux-amd64[a-zA-Z0-9./?=_%:-]*.tar.gz"
</strong>BINARIES_URL="$(curl -s $RELEASE_URL | grep -Eo $FILE | head -1)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O geth.tar.gz $BINARIES_URL
tar -xzvf geth.tar.gz -C $HOME
rm geth.tar.gz
sudo mv $HOME/geth-* geth
</code></pre>

Install the binaries.

```bash
sudo mv $HOME/geth/geth /usr/local/bin
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install Go dependencies. Latest version [available here](https://go.dev/dl/).

```bash
wget -O go.tar.gz <LATEST VERSION URL FROM ABOVE>
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go.tar.gz
echo export PATH=$PATH:/usr/local/go/bin >> $HOME/.bashrc
source $HOME/.bashrc
```

Verify Go is properly installed by checking the version and cleanup files.

```bash
go version
rm go.tar.gz
```

Install build dependencies.

```bash
sudo apt-get update
sudo apt install build-essential git
```

Build the binary.

```bash
mkdir -p ~/git
cd ~/git
git clone -b master https://github.com/ethereum/go-ethereum.git
cd go-ethereum
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
make geth
```

Install the binary.

<pre class="language-bash"><code class="lang-bash"><strong>sudo cp $HOME/git/go-ethereum/build/bin/geth /usr/local/bin
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

<pre class="language-bash"><code class="lang-bash">[Unit]
Description=Geth Execution Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/geth \
    --hoodi \
    --port 30303 \
    --http.port 8545 \
    --authrpc.port 8551 \
    --maxpeers 50 \
    --metrics \
    --http \
    --datadir=/var/lib/geth \
    --pprof \
    --state.scheme=path \
    --authrpc.jwtsecret=/secrets/jwtsecret
   
<strong>[Install]
</strong>WantedBy=multi-user.target
</code></pre>

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

<pre class="language-bash"><code class="lang-bash"><strong>sudo journalctl -fu execution | ccze
</strong></code></pre>

A properly functioning **Geth** execution client will indicate "Imported new potential chain segment". For example,

```
geth[4531]: INFO [02-04|01:20:48.280] Chain head was updated    number=16000 hash=2317ae..c41107
geth[4531]: INFO [02-04|01:20:49.648] Imported new potential chain segment       number=16000 hash=ab173f..33a21b
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/geth/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Erigon

{% hint style="info" %}
**Erigon** - Successor to OpenEthereum, Erigon is an implementation of Ethereum (aka "Ethereum client"), on the efficiency frontier, written in Go.
{% endhint %}

## Overview

#### Official Links

| Subject       | Link                                                  |
| ------------- | ----------------------------------------------------- |
| Releases      | <https://github.com/erigontech/erigon/releases>       |
| Documentation | [https://docs.erigon.tech](https://docs.erigon.tech/) |
| Website       | [https://erigon.tech](https://erigon.tech/)           |

### 1. Initial configuration

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/erigon
sudo chown -R execution:execution /var/lib/erigon
```

Install dependencies.

```bash
sudo apt install curl libsnappy-dev libc6-dev jq libc6 unzip -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/erigontech/erigon/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux_amd64.tar.gz)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O erigon.tar.gz $BINARIES_URL
tar -xzvf erigon.tar.gz -C $HOME
mv erigon_* erigon
```

Install the binaries and cleanup.

```bash
sudo mv $HOME/erigon/erigon /usr/local/bin
rm -rf erigon erigon.tar.gz
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install Go dependencies. Latest version [available here](https://go.dev/dl/).

```bash
wget -O go.tar.gz <LATEST VERSION URL FROM ABOVE>
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go.tar.gz
echo export PATH=$PATH:/usr/local/go/bin >> $HOME/.bashrc
source $HOME/.bashrc
```

Verify Go is properly installed by checking the version and cleanup files.

```bash
go version
rm go.tar.gz
```

Install build dependencies.

```bash
sudo apt-get update
sudo apt install build-essential git
```

Build the binary.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/erigontech/erigon.git
cd erigon
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
make erigon
```

Install the binary.

<pre class="language-bash"><code class="lang-bash"><strong>sudo cp $HOME/git/erigon/build/bin/erigon /usr/local/bin
</strong></code></pre>

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Erigon Execution Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/erigon \
   --datadir /var/lib/erigon \
   --chain hoodi \
   --port 30303 \
   --torrent.port 42069 \
   --maxpeers 50 \
   --private.api.addr 127.0.0.1:9099 \
   --authrpc.port 8551 \
   --http.api web3,eth,net,engine \
   --metrics \
   --pprof \
   --prune.mode minimal \
   --authrpc.jwtsecret=/secrets/jwtsecret \
   --externalcl=true

[Install]
WantedBy=multi-user.target
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu execution | ccze
```

A properly functioning **Erigon** execution client will indicate "Handling new payload". For example,

```
erigon[3]: [INFO] [09-29|03:36:24.689] [NewPayload] Handling new payload        height=19999 hash=0xea060...2846a907ceb4
erigon[3]: [INFO] [09-29|03:36:25.278] [updateForkchoice] Fork choice update: flushing in-memory state (built by previous newPayload)
erigon[3]: [INFO] [09-29|03:36:25.280] RPC Daemon notified of new headers       from=19998 to=19999 hash=0xeeed..710b597 header sending=13.32µs log sending=290ns
erigon[3]: [INFO] [09-29|03:36:25.280] head updated                             hash=0xea06098ad5e...5e5f43 number=20000
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/erigon/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Reth

## Overview

{% hint style="info" %}
**Reth** - short for Rust Ethereum, is an Ethereum full node implementation that is focused on being user-friendly, highly modular, as well as being fast and efficient.
{% endhint %}

#### Official Links

| Subject       | Link                                  |
| ------------- | ------------------------------------- |
| Releases      | <https://github.com/paradigmxyz/reth> |
| Documentation | <https://paradigmxyz.github.io/reth/> |
| Website       | <https://www.paradigm.xyz/oss/reth>   |

### 1. Create service account and data directory

Create a service user for the execution service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group execution
sudo mkdir -p /var/lib/reth
sudo chown -R execution:execution /var/lib/reth
```

Install dependencies.

```bash
sudo apt-get update
sudo apt install -y ccze jq curl
```

### **2. Install binaries**

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

```bash
RELEASE_URL="https://api.github.com/repos/paradigmxyz/reth/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r '.assets[] | select(.name | startswith ("reth")) | .browser_download_url' | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O reth.tar.gz $BINARIES_URL
tar -xzvf reth.tar.gz -C $HOME
rm reth.tar.gz
```

Install the binaries and display the version.

```bash
sudo mv $HOME/reth /usr/local/bin
reth --version
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

**Install rust dependency**

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

When prompted, enter '1' to proceed with the default install.

Update your environment variables.

```bash
echo export PATH="$HOME/.cargo/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
```

Install rust dependencies.

```bash
sudo apt-get update
sudo apt install -y git libclang-dev pkg-config build-essential
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/paradigmxyz/reth.git
cd reth
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build the release
cargo build --release --features jemalloc
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
cargo build --release --features jemalloc
```

Verify Reth was built properly by checking the version number.

```bash
~/git/reth/target/release/reth --version
```

Install the binary.

```bash
sudo cp ~/git/reth/target/release/reth /usr/local/bin
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `execution.service` configuration.

```bash
sudo nano /etc/systemd/system/execution.service
```

Paste the following configuration into the file.

<pre class="language-bash"><code class="lang-bash">[Unit]
Description=Reth Execution Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=execution
Group=execution
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment=RUST_LOG=info
ExecStart=/usr/local/bin/reth node \
    --full \
    --chain hoodi \
    --datadir=/var/lib/reth \
    --metrics 127.0.0.1:6060 \
    --port 30303 \
    --discovery.port 30303 \
    --enable-discv5-discovery \
    --discovery.v5.port 30304 \
    --http \
    --http.port 8545 \
    --http.api="rpc,eth,web3,net,debug" \
    --log.file.directory=/var/lib/reth/logs \
    --max-outbound-peers 25 \
    --max-inbound-peers 25 \
    --authrpc.jwtsecret=/secrets/jwtsecret
   
<strong>[Install]
</strong>WantedBy=multi-user.target
</code></pre>

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable execution
```

Finally, start your execution layer client and check it's status.

```bash
sudo systemctl start execution
sudo systemctl status execution
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful execution client commands

{% tabs %}
{% tab title="View Logs" %}

<pre class="language-bash"><code class="lang-bash"><strong>sudo journalctl -fu execution | ccze
</strong></code></pre>

A properly functioning **Reth** execution client will indicate "Block added to canonical chain". For example,

```
INFO reth::node::events: Forkchoice updated head_block_hash=2317ae..c41107 safe_block_hash=ab173f..33a21b finalized_block_hash=ab173f..33a21b status=Valid
INFO reth::node::events: Block added to canonical chain number=16000 hash=2317ae..c41107
INFO reth::node::events: Canonical chain committed number=16000 hash=2317ae..c41107 elapsed=12.508272ms
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop execution
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start execution
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status execution
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* Recovering from a corrupted database due to power outage or hardware failure
* Re-syncing to reduce disk space usage
* Upgrading to a new storage format

```bash
sudo systemctl stop execution
sudo rm -rf /var/lib/reth/*
sudo systemctl restart execution
```

Time to re-sync the execution client can take a few hours up to a day.
{% endtab %}
{% endtabs %}

Now that your execution client is configured and started, proceed to the next step on setting up your consensus client.

{% hint style="warning" %}
If you're checking the logs and see any warnings or errors, please be patient as these will normally resolve once both your execution and consensus clients are fully synced to the Ethereum network.
{% endhint %}


# Step 4: Installing consensus client

Your choice of either Lighthouse, Lodestar, Teku, Nimbus, or Prysm.

{% hint style="warning" %}
Only one consensus client is required per node.
{% endhint %}

## **Consensus Client Diversity**

* To strengthen Ethereum's resilience against potential attacks or consensus bugs, it's best practice to run a minority client in order to increase client diversity.
* Find the latest distribution of consensus clients here: [https://clientdiversity.org](https://clientdiversity.org/)

<figure><img src="/files/t6VDQN5IEZ6XFhsab8xq" alt=""><figcaption><p>CL Diversity as of Dec 2024</p></figcaption></figure>

## Overview of Consensus Clients

{% hint style="info" %}
:shield: **Recommendation** :shield:: Teku, Nimbus, or Lodestar
{% endhint %}

### Lighthouse

* Lighthouse: Open-source Ethereum 2.0 project by Sigma Prime, following Ethereum Foundation Research specification.
* Innovative features: Implements advanced blockchain technologies like proof-of-stake consensus, parallel transaction execution, and sharding (state separation).
* Independently managed: Not officially affiliated with the Ethereum Foundation, adheres to their guidance as long beneficial for Ethereum protocol and community.
* Implemented in Rust: Prioritizes security and efficiency through language choice.

### Lodestar

* Lodestar: Open-source Ethereum consensus client by ChainSafe Systems, known for production-ready beacon chain and validator client.
* Flagship product: Ideal for researchers and developers due to rapid prototyping and browser usage capabilities.
* Typescript implementation: Distinctive feature, aligns with familiarity of millions of developers worldwide.
* Light client expertise: Pioneering research, standardization, and implementation of Ethereum light clients.
* Collaborative approach: Works with other implementers, researchers, and developers to promote trustless data usage from the blockchain.

### Teku

* Teku (formerly Artemis): Enterprise-focused Ethereum consensus client developed by PegaSys, an ConsenSys division.
* Apache 2.0 licensed: Open-source with flexible usage permissions.
* Written in Java: Mature and widely used programming language for increased institutional appeal and security requirements.
* Developed by PegaSys: An arm of ConsenSys dedicated to creating enterprise-ready Ethereum clients and tools.

### Nimbus

* Nimbus: Open-source Ethereum client compatible with both Ethereum 2.0 and Ethereum 1.0.
* Lightweight resource usage: Designed for optimal performance on embedded systems and resource-restricted devices.
* Versatile application: Also suitable for running alongside other workloads, beneficial for stakers looking to minimize server costs.
* Implemented in Nim: Written using the Nim programming language.
* Maintained by Status.im team.

### Prysm

* Prysm: Full-featured Ethereum 2.0 implementation in Go programming language.
* Developed by Prysmatic Labs.
* Adheres to official Ethereum 2.0 specification, evolving collectively through research and development efforts from various Ethereum ecosystem teams including the Ethereum Foundation.

## Comparison of Consensus Clients

<table><thead><tr><th>Client</th><th width="108">CPU Use</th><th width="111">RAM Use</th><th>Database Size</th><th>Time to sync head</th></tr></thead><tbody><tr><td><strong>Lighthouse</strong></td><td>Medium</td><td>6 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Lodestar</strong></td><td>Medium</td><td>8 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Teku</strong></td><td>Medium</td><td>10 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Nimbus</strong></td><td>Low</td><td>3 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr><tr><td><strong>Prysm</strong></td><td>Medium</td><td>6 GB</td><td>120 - 150 GB</td><td>Instant via checkpoint</td></tr></tbody></table>

#### Notes:

* As databases expand beyond 300GB in size over time, checkpoint sync allows nodes to efficiently resynchronize and significantly reduce their database sizes while minimizing downtime.


# Lighthouse

## Overview

{% hint style="info" %}
[Lighthouse](https://github.com/sigp/lighthouse) is an Eth client with a heavy focus on speed and security. The team behind it, [Sigma Prime](https://sigmaprime.io), is an information security and software engineering firm who have funded Lighthouse along with the Ethereum Foundation, Consensys, and private individuals. Lighthouse is built in Rust and offered under an Apache 2.0 License.
{% endhint %}

#### Official Links

| Subject       | Links                                                                           |
| ------------- | ------------------------------------------------------------------------------- |
| Releases      | <https://github.com/sigp/lighthouse/releases>                                   |
| Documentation | [https://lighthouse-book.sigmaprime.io](https://lighthouse-book.sigmaprime.io/) |
| Website       | [https://lighthouse.sigmaprime.io](https://lighthouse.sigmaprime.io/)           |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/lighthouse
sudo chown -R consensus:consensus /var/lib/lighthouse
```

Install dependencies.

```bash
sudo apt install curl ccze jq -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/sigp/lighthouse/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lighthouse.tar.gz $BINARIES_URL
# Untar
tar -xzvf lighthouse.tar.gz -C $HOME
# Cleanup
rm lighthouse.tar.gz
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/lighthouse /usr/local/bin/lighthouse
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

**Install rust dependency**

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

When prompted, enter '1' to proceed with the default install.

Update your environment variables.

```bash
echo export PATH="$HOME/.cargo/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
```

Install rust dependencies.

```bash
sudo apt-get update
sudo apt install -y git gcc g++ make cmake pkg-config libssl-dev libclang-dev clang protobuf-compiler
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone -b stable https://github.com/sigp/lighthouse.git
cd lighthouse
make
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
make
```

Verify lighthouse was built properly by checking the version number.

```
lighthouse --version
```

Install the binary.

```bash
sudo cp $HOME/.cargo/bin/lighthouse /usr/local/bin/lighthouse
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Lighthouse Consensus Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/lighthouse bn \
  --datadir /var/lib/lighthouse \
  --network hoodi \
  --staking \
  --validator-monitor-auto \
  --metrics \
  --checkpoint-sync-url=https://hoodi.beaconstate.ethstaker.cc \
  --port 9000 \
  --quic-port 9001 \
  --http-port 5052 \
  --target-peers 100 \
  --metrics-port 8008 \
  --execution-endpoint http://127.0.0.1:8551 \
  --execution-jwt /secrets/jwtsecret

[Install]
WantedBy=multi-user.target
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus client is up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

Press `Ctrl` + `C` to exit the logs.

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Lighthouse Consensus Client Logs**

```bash
Feb 03 01:02:36.000 INFO New block received                      root: 0xb5ccb2f85d981ca9e1c0d904f967403ddf8c47532c195fe213c94a28ffaf6a2e, slot: 2138
Feb 03 01:02:42.000 INFO Synced                                  slot: 2138, block: 0x1cb281a, epoch: 121, finalized_epoch: 120, finalized_root: 0x1dce0, exec_hash: 0x6827aeb (verified), peers: 50, service: slot_notifier
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/lighthouse/beacon
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Lodestar

## Overview

{% hint style="info" %}
[Lodestar ](https://lodestar.chainsafe.io)is a Typescript implementation of the official Ethereum specification by the [ChainSafe.io](https://lodestar.chainsafe.io) team. In addition to the beacon chain client, the team is also working on 22 packages and libraries. A complete list can be found [here](https://hackmd.io/CcsWTnvRS_eiLUajr3gi9g). Finally, the Lodestar team is leading in light client research and development and has received funding from the EF and Moloch DAO for this purpose.
{% endhint %}

#### Official Links

| Subject       | Links                                                                         |
| ------------- | ----------------------------------------------------------------------------- |
| Releases      | <https://github.com/ChainSafe/lodestar/releases>                              |
| Documentation | [https://chainsafe.github.io/lodestar](https://chainsafe.github.io/lodestar/) |
| Website       | [https://lodestar.chainsafe.io](https://lodestar.chainsafe.io/)               |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/lodestar
sudo chown -R consensus:consensus /var/lib/lodestar
```

Install dependencies.

```bash
sudo apt-get install gcc g++ make git curl ccze -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ChainSafe/lodestar/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://github.com/ChainSafe/lodestar/releases/download/${LATEST_TAG}/lodestar-${LATEST_TAG}-linux-amd64.tar.gz"
	
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lodestar.tar.gz $BINARIES_URL
# Untar
tar -xzvf lodestar.tar.gz -C $HOME
# Cleanup
rm lodestar.tar.gz
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mkdir -p /usr/local/bin/lodestar
</strong><strong>sudo mv $HOME/lodestar /usr/local/bin/lodestar
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install yarn.

```bash
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install yarn -y
```

Confirm yarn is installed properly.

```bash
yarn --version
# Should output version >= 1.22.19
```

Install nodejs.

```bash
#Download and import the Nodesource GPG key
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

#Create deb repository
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

#Run Update and Install
sudo apt-get update
sudo apt-get install nodejs -y
```

Install and build Lodestar.

```bash
mkdir -p ~/git
cd ~/git
git clone -b stable https://github.com/chainsafe/lodestar.git
cd lodestar
yarn install
yarn run build
```

Verify Lodestar was installed properly by displaying the version.

```bash
./lodestar --version
```

Sample output of a compatible version.

```
🌟 Lodestar: TypeScript Implementation of the Ethereum Consensus Beacon Chain.
  * Version: v1.8.0/stable/a4b29cf
  * by ChainSafe Systems, 2018-2022
```

Install the binaries.

```bash
sudo cp -a $HOME/git/lodestar /usr/local/bin/lodestar
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

```shell
[Unit]
Description=Lodestar Consensus Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
WorkingDirectory=/usr/local/bin/lodestar
ExecStart=/usr/local/bin/lodestar/lodestar beacon \
  --dataDir /var/lib/lodestar \
  --network hoodi \
  --rest.port 5052 \
  --port 9000 \
  --targetPeers 100 \
  --metrics.port 8008 \
  --metrics true \
  --checkpointSyncUrl https://hoodi.beaconstate.ethstaker.cc \
  --jwt-secret /secrets/jwtsecret \
  --execution.urls http://127.0.0.1:8551 \
  --suggestedFeeRecipient <0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replace`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the whole line beginning with

```
--suggestedFeeRecipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Lodestar Consensus Client Logs**

```bash
Mar-19 04:09:49.000    info: Synced - slot: 3338 - head: 3355 0x5abb_ac30 - execution: valid(0x1a3c_2ca5) - finalized: 0xfa22_1142:3421 - peers: 25
Mar-19 04:09:52.000    info: Synced - slot: 3339 - head: 3356 0xcd2a_8b32 - execution: valid(0xab34_fa32) - finalized: 0xfa22_1142:3421 - peers: 25
Mar-19 04:09:04.000    info: Synced - slot: 3340 - head: 3357 0xff1a_f12a - execution: valid(0xfaf1_b35f) - finalized: 0xfa22_1142:3421 - peers: 25
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/lodestar/chain-db
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Teku

## Overview

{% hint style="info" %}
[PegaSys Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) (formerly known as Artemis) is a Java-based Ethereum client designed & built to meet institutional needs and security requirements. PegaSys is an arm of [ConsenSys](https://consensys.net) dedicated to building enterprise-ready clients and tools for interacting with the core Ethereum platform. Teku is Apache 2 licensed and written in Java, a language notable for its materity & ubiquity.
{% endhint %}

{% hint style="info" %}
**Note**: Teku is configured to run both **validator client** and **beacon chain client** in one process.
{% endhint %}

#### Official Links

| Subject       | Links                                                                                                         |
| ------------- | ------------------------------------------------------------------------------------------------------------- |
| Releases      | <https://github.com/ConsenSys/teku/releases>                                                                  |
| Documentation | <https://docs.teku.consensys.net/introduction>                                                                |
| Website       | [https://consensys.net/knowledge-base/ethereum-2/teku](https://consensys.net/knowledge-base/ethereum-2/teku/) |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/teku
sudo chown -R consensus:consensus /var/lib/teku
```

Install dependencies.

```bash
sudo apt install curl ccze openjdk-21-jdk libsnappy-dev libc6-dev jq git libc6 unzip -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ConsenSys/teku/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://artifacts.consensys.net/public/teku/raw/names/teku.tar.gz/versions/${LATEST_TAG}/teku-${LATEST_TAG}.tar.gz"
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O teku.tar.gz $BINARIES_URL
# Untar
tar -xzvf teku.tar.gz -C $HOME
# Rename folder
mv teku-${LATEST_TAG} teku
# Cleanup
rm teku.tar.gz
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv $HOME/teku /usr/local/bin/teku
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/ConsenSys/teku.git
cd teku
# Get new tags
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/ConsenSys/teku/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
./gradlew distTar installDist
```

Verify Teku was built properly by displaying the version.

```shell
cd $HOME/git/teku/build/install/teku/bin
./teku --version
```

Install the binaries.

```shell
sudo cp -a $HOME/git/teku/build/install/teku /usr/local/bin/teku
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

{% tabs %}
{% tab title="Standalone Beacon Node (Recommended)" %}

```shell
[Unit]
Description=Teku Beacon Node Consensus Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment=JAVA_OPTS=-Xmx6g
Environment=TEKU_OPTS=-XX:-HeapDumpOnOutOfMemoryError
ExecStart=/usr/local/bin/teku/bin/teku \
  --network=hoodi \
  --data-path=/var/lib/teku/ \
  --data-storage-mode="minimal" \
  --checkpoint-sync-url="https://hoodi.beaconstate.ethstaker.cc" \
  --ee-endpoint=http://127.0.0.1:8551 \
  --ee-jwt-secret-file=/secrets/jwtsecret \
  --rest-api-enabled=true \
  --rest-api-port=5052 \
  --p2p-port=9000 \
  --p2p-peer-upper-bound=100 \
  --p2p-peer-lower-bound=60 \
  --metrics-enabled=true \
  --metrics-port=8008 \
  --validators-proposer-default-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the line beginning with

```
--validators-proposer-default-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.
{% endtab %}

{% tab title="Combined BN+VC" %}
{% hint style="info" %}
This configuration combines the beacon chain and validator into one running service. While it is simpler to manage and run, this configuration is less flexible when it comes to running EL+CL failover nodes or in times you wish to resync your execution client and temporarily use [Rocket Pool's Rescue Node](https://rescuenode.com/docs/how-to-connect/solo).
{% endhint %}

```shell
[Unit]
Description=Teku Beacon Node + Validator Consensus Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
Environment=JAVA_OPTS=-Xmx6g
Environment=TEKU_OPTS=-XX:-HeapDumpOnOutOfMemoryError
ExecStart=/usr/local/bin/teku/bin/teku \
  --network=hoodi \
  --data-path=/var/lib/teku/ \
  --data-storage-mode="minimal" \
  --initial-state="https://hoodi.beaconstate.ethstaker.cc" \
  --ee-endpoint=http://127.0.0.1:8551 \
  --ee-jwt-secret-file=/secrets/jwtsecret \
  --rest-api-enabled=true \
  --rest-api-port=5052 \
  --p2p-port=9000 \
  --p2p-peer-upper-bound=100 \
  --p2p-peer-lower-bound=60 \
  --metrics-enabled=true \
  --metrics-port=8008 \
  --validator-keys=/var/lib/teku/validator_keys:/var/lib/teku/validator_keys \
  --validators-graffiti="🏠🥩🪙🛡️" \
  --validators-proposer-default-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the whole three lines beginning with

```
--validator-keys
--validators-graffiti
--validators-proposer-default-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.
{% endtab %}
{% endtabs %}

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus clients are up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Consensus Client Logs**

```bash
teku[64122]: 02:24:28.010 INFO  - Slot Event  *** Slot: 19200, Block: 1468A43F874EDE790DB6B499A51003500B5BA85226E9500A7A187DB9A169DE20, Justified: 1132, Finalized: 1133, Peers: 70
teku[64122]: 02:24:40.010 INFO  - Slot Event  *** Slot: 19200, Block: 72B092AADFE146F5D3F395A720C0AA3B2354B2095E3F10DC18F0E9716D286DCB, Justified: 1132, Finalized: 1133, Peers: 70
```

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Teku Consensus Client Logs**

```bash
teku[64122]: 02:24:28.010 INFO  - Slot Event  *** Slot: 19200, Block: 1468A43F874EDE790DB6B499A51003500B5BA85226E9500A7A187DB9A169DE20, Justified: 1132, Finalized: 1133, Peers: 70
teku[64122]: 02:24:40.010 INFO  - Slot Event  *** Slot: 19200, Block: 72B092AADFE146F5D3F395A720C0AA3B2354B2095E3F10DC18F0E9716D286DCB, Justified: 1132, Finalized: 1133, Peers: 70
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/teku/beacon
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Nimbus

## Overview

{% hint style="info" %}
[Nimbus](https://our.status.im/tag/nimbus/) is a research project and a client implementation for Ethereum designed to perform well on embedded systems and personal mobile devices, including older smartphones with resource-restricted hardware. The Nimbus team are from [Status](https://status.im/about/) the company best known for [their messaging app/wallet/Web3 browser](https://status.im) by the same name. Nimbus (Apache 2) is written in Nim, a language with Python-like syntax that compiles to C.
{% endhint %}

{% hint style="info" %}
**Note**: Nimbus is configured to run both **validator client** and **beacon chain client** in one process.
{% endhint %}

#### Official Links

| Subject       | Links                                                                 |
| ------------- | --------------------------------------------------------------------- |
| Releases      | <https://github.com/status-im/nimbus-eth2/releases>                   |
| Documentation | [https://nimbus.guide](https://nimbus.guide/)                         |
| Website       | [https://our.status.im/tag/nimbus](https://our.status.im/tag/nimbus/) |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/nimbus
sudo chown -R consensus:consensus /var/lib/nimbus
```

Install dependencies.

```bash
sudo apt install curl libsnappy-dev libc6-dev jq libc6 unzip ccze -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/status-im/nimbus-eth2/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep _Linux_amd64.*.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O nimbus.tar.gz $BINARIES_URL
# Untar
tar -xzvf nimbus.tar.gz -C $HOME
# Rename folder
mv nimbus-eth2_Linux_amd64_* nimbus
# Cleanup
rm nimbus.tar.gz
```

Install the binaries, display version and cleanup.

```bash
sudo mv nimbus/build/nimbus_beacon_node /usr/local/bin
sudo mv nimbus/build/nimbus_validator_client /usr/local/bin
nimbus_beacon_node --version
rm -r nimbus
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install dependencies.

```bash
sudo apt-get update
sudo apt-get install curl build-essential git -y
```

Build the binary.

```bash
mkdir -p ~/git
cd ~/git
git clone -b stable https://github.com/status-im/nimbus-eth2
cd nimbus-eth2
make -j$(nproc) update
make -j$(nproc) nimbus_beacon_node
make -j$(nproc) nimbus_validator_client
```

Verify Nimbus was built properly by displaying the version.

```bash
cd $HOME/git/nimbus-eth2/build
./nimbus_beacon_node --version
```

Install the binary.

```bash
sudo cp $HOME/git/nimbus-eth2/build/nimbus_beacon_node /usr/local/bin
sudo cp $HOME/git/nimbus-eth2/build/nimbus_validator_client /usr/local/bin
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

{% tabs %}
{% tab title="Standalone Beacon Node (Recommended)" %}

```shell
[Unit]
Description=Nimbus Consensus Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/nimbus_beacon_node \
  --network=hoodi \
  --data-dir=/var/lib/nimbus \
  --tcp-port=9000 \
  --udp-port=9000 \
  --max-peers=100 \
  --rest-port=5052 \
  --enr-auto-update=true \
  --non-interactive \
  --status-bar=false \
  --in-process-validators=false \
  --web3-url=http://127.0.0.1:8551 \
  --rest \
  --metrics \
  --metrics-port=8008 \
  --jwt-secret="/secrets/jwtsecret" \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

{% endtab %}

{% tab title="Combined (BN+VC)" %}
{% hint style="info" %}
This configuration combines the beacon chain and validator into one running service. While it is simpler to manage and run, this configuration is less flexible when it comes to running EL+CL failover nodes or in times you wish to resync your execution client and temporarily use [Rocket Pool's Rescue Node](https://rescuenode.com/docs/how-to-connect/solo).
{% endhint %}

```shell
[Unit]
Description=Nimbus Consensus Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/nimbus_beacon_node \
  --network=hoodi \
  --data-dir=/var/lib/nimbus \
  --tcp-port=9000 \
  --udp-port=9000 \
  --max-peers=100 \
  --rest-port=5052 \
  --enr-auto-update=true \
  --web3-url=http://127.0.0.1:8551 \
  --rest \
  --metrics \
  --metrics-port=8008 \
  --jwt-secret="/secrets/jwtsecret" \
  --graffiti="🏠🥩🪙🛡️" \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

{% endtab %}
{% endtabs %}

* Replace `<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, use the Standalone Beacon Node configuration and delete the whole line beginning with

```
--suggested-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to quickly sync with Checkpoint Sync.

{% hint style="info" %}
Checkpoint sync allows you to start your consensus layer within minutes instead of days.
{% endhint %}

```bash
sudo -u consensus /usr/local/bin/nimbus_beacon_node trustedNodeSync \
--network=hoodi \
--trusted-node-url=https://hoodi.beaconstate.ethstaker.cc \
--data-dir=/var/lib/nimbus \
--backfill=false
```

When the checkpoint sync is complete, you'll see the following message:

> Done, your beacon node is ready to serve you! Don't forget to check that you're on the canonical chain by comparing the checkpoint root with other online sources. See <https://nimbus.guide/trusted-node-sync.html> for more information.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus clients are up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Consensus Client Logs**

```
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:00.000+00:00 Slot start       topics="beacnde" slot=31205 epoch=903 sync=synced peers=80 head=13a131:31204 finalized=1111:cdba33411 delay=69us850ns
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:08.000+00:00 Slot end         topics="beacnde" slot=31205 nextActionWait=7m27s985ms126us530ns nextAttestationSlot=31235 nextProposalSlot=-1 syncCommitteeDuties=none head=13a131:31204
```

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Nimbus Consensus Client Logs**

```bash
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:00.000+00:00 Slot start       topics="beacnde" slot=31205 epoch=903 sync=synced peers=80 head=13a131:31204 finalized=1111:cdba33411 delay=69us850ns
nimbus_beacon_node[292966]: INF 2023-02-05 01:20:08.000+00:00 Slot end         topics="beacnde" slot=31205 nextActionWait=7m27s985ms126us530ns nextAttestationSlot=31235 nextProposalSlot=-1 syncCommitteeDuties=none head=13a131:31204
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/nimbus/db

#Perform checkpoint sync
sudo -u consensus /usr/local/bin/nimbus_beacon_node trustedNodeSync \
--network=hoodi \
--trusted-node-url=https://hoodi.beaconstate.ethstaker.cc \
--data-dir=/var/lib/nimbus \
--backfill=false

sudo systemctl restart consensus
```

With checkpoint sync, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Prysm

## Overview

{% hint style="info" %}
[Prysm](https://github.com/prysmaticlabs/prysm) is a Go implementation of Ethereum protocol with a focus on usability, security, and reliability. Prysm is developed by [Prysmatic Labs](https://prysmaticlabs.com), a company with the sole focus on the development of their client. Prysm is written in Go and released under a GPL-3.0 license.
{% endhint %}

#### Official Links

| Subject       | Links                                            |
| ------------- | ------------------------------------------------ |
| Releases      | <https://github.com/OffchainLabs/prysm/releases> |
| Documentation | <https://www.offchainlabs.com/prysm/docs>        |
| Website       | <https://www.offchainlabs.com/prysm/docs>        |

### 1. Initial configuration

Create a service user for the consensus service, create data directory and assign ownership.

```bash
sudo adduser --system --no-create-home --group consensus
sudo mkdir -p /var/lib/prysm/beacon
sudo chown -R consensus:consensus /var/lib/prysm/beacon
```

Install dependencies.

```bash
sudo apt install curl jq git ccze -y
```

### 2. Install Binaries

* Downloading binaries is often faster and more convenient.
* Building from source code can offer better compatibility and is more aligned with the spirit of FOSS (free open source software).

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest binaries.

```bash
cd $HOME
prysm_version=$(curl -f -s https://prysmaticlabs.com/releases/latest)
file_beacon=beacon-chain-${prysm_version}-linux-amd64
file_validator=validator-${prysm_version}-linux-amd64
curl -f -L "https://prysmaticlabs.com/releases/${file_beacon}" -o beacon-chain
curl -f -L "https://prysmaticlabs.com/releases/${file_validator}" -o validator
chmod +x beacon-chain validator
```

Install the binaries.

<pre class="language-bash"><code class="lang-bash"><strong>sudo mv beacon-chain validator /usr/local/bin
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Install Go dependencies. Latest version [available here](https://go.dev/dl/).

```bash
wget -O go.tar.gz <LATEST VERSION URL FROM ABOVE>
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go.tar.gz
echo export PATH=$PATH:/usr/local/go/bin >> $HOME/.bashrc
source $HOME/.bashrc
```

Verify Go is properly installed by checking the version and cleanup files.

```bash
go version
rm go.tar.gz
```

Install build dependencies.

```bash
sudo apt-get update
sudo apt install build-essential git
```

Build the binaries.

```bash
mkdir -p ~/git
cd ~/git
git clone https://github.com/OffchainLabs/prysm.git
cd prysm
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/OffchainLabs/prysm/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
go build -o=./build/beacon-chain ./cmd/beacon-chain
go build -o=./build/validator ./cmd/validator
```

Install the binaries.

```shell
sudo cp $HOME/git/prysm/build/beacon-chain /usr/local/bin
sudo cp $HOME/git/prysm/build/validator /usr/local/bin
```

</details>

### **3. Setup and configure systemd**

Create a **systemd unit file** to define your `consensus.service` configuration.

```bash
sudo nano /etc/systemd/system/consensus.service
```

Paste the following configuration into the file.

<pre class="language-bash"><code class="lang-bash"><strong>[Unit]
</strong>Description=Prysm Consensus Layer Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=consensus
Group=consensus
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/beacon-chain \
  --hoodi \
  --datadir=/var/lib/prysm/beacon \
  --grpc-gateway-port 5052 \
  --p2p-tcp-port 13000 \
  --p2p-udp-port 12000 \
  --p2p-max-peers 80 \
  --monitoring-port 8008 \
  --checkpoint-sync-url=https://hoodi.beaconstate.ethstaker.cc \
  --execution-endpoint=http://localhost:8551 \
  --jwt-secret=/secrets/jwtsecret \
  --accept-terms-of-use=true \
  --suggested-fee-recipient=&#x3C;0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
</code></pre>

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* **Not staking?** If you only want a full node, delete the whole lines beginning with

```
--suggested-fee-recipient
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable consensus
```

Finally, start your consensus layer client and check it's status.

```bash
sudo systemctl start consensus
sudo systemctl status consensus
```

Press `Ctrl` + `C` to exit the status.

Check your logs to confirm that the consensus clients are up and syncing.

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Consensus Client Logs**

```bash
"Peer summary" activePeers=69 inbound=0 outbound=69 prefix=p2p
"Synced new block" block=0xb5ccb2f85... epoch=1837 finalizedEpoch=1838 finalizedRoot=0x1dce0... prefix=blockchain slot=21338 "Finished applying state transition" attestations=128 payloadHash=0x000000000000 prefix=blockchain slot=2138 syncBitsCount=213 txCount=0"terminal difficulty has not been reached yet" latestDifficulty=10000000 prefix=powchain terminalDifficulty=10000000
```

### 4. Helpful consensus client commands

{% tabs %}
{% tab title="View Logs" %}

```bash
sudo journalctl -fu consensus | ccze
```

**Example of Synced Prysm Consensus Client Logs**

```bash
time="2023-02-02 11:21:00" level=info msg="Peer summary" activePeers=35 inbound=10 outbound=25 prefix=p2p
time="2023-02-02 11:21:00" level=info msg="Synced new block" block=0xd9ddeza1289... epoch=11795 finalizedEpoch=111794 finalizedRoot=0x462e3275... prefix=blockchain slot=31205
time="2023-02-02 11:21:00" level=info msg="Finished applying state transition" attestations=64 payloadHash=0x000000000000 prefix=blockchain slot=31205 syncBitsCount=209 txCount=0
```

{% endtab %}

{% tab title="Stop" %}

```bash
sudo systemctl stop consensus
```

{% endtab %}

{% tab title="Start" %}

```bash
sudo systemctl start consensus
```

{% endtab %}

{% tab title="View Status" %}

```bash
sudo systemctl status consensus
```

{% endtab %}

{% tab title="Reset Database" %}
Common reasons to reset the database can include:

* To reduce disk space usage
* To recover from a corrupted database due to power outage or hardware failure
* To upgrade to a new storage format

```bash
sudo systemctl stop consensus
sudo rm -rf /var/lib/prysm/beacon/beaconchaindata
sudo systemctl restart consensus
```

With checkpoint sync enabled, time to re-sync the consensus client should take only a minute or two.
{% endtab %}
{% endtabs %}

Now that your consensus client is configured and started, you have a full node.

Proceed to the next step on setting up your validator client, which turns a full node into a staking node.

{% hint style="info" %}
If you wanted to setup a full node, not a staking node, stop here! Congrats on running your own full node! :tada:
{% endhint %}


# Step 5: Installing Validator


# Setting up Validator Keys

## :seedling: 1. Obtain testnet ETH

<details>

<summary>Option 1: Ethstaker's #cheap-hoodi-validator Channel</summary>

* **Step 1**: Visit the [Ethstaker Discord](https://discord.io/ethstaker) and join the #cheap-hoodi-validator channel
* **Step 2**: Use the `/cheap-hoodi-deposit` slash command and follow the instructions from the bot. You need to start typing the slash command and it will show above your input box where you can use it.
* **Requirement**: In order to use the cheap hoodi validator process, you must now set your withdrawal address to `0x4D496CcC28058B1D74B7a19541663E21154f9c84` when creating your validator keys and deposit file. This is to prevent abuses of this service.

</details>

<details>

<summary>Option 2: Use faucets from pk910 / axol.io</summary>

* pk910: <https://hoodi-faucet.pk910.de>
* axol.io: [https://faucet.axol.io](https://faucet.axol.io/)

</details>

## :key: 2. Generate validator keys

#### Before continuing please have the following:

* [ ] **Hardware wallet address or** **Safe multisig wallet** **address**: This is for your [Withdrawal Address](https://notes.ethereum.org/@launchpad/withdrawals-faq#Q-What-are-the-two-types-of-withdrawals). It must be in checksum format, which means some letters are UPPERCASE. If needed, validate your address's checksum format against a block explorer, such as <https://etherscan.io>

{% hint style="info" %}
Safe {Wallet} Multisig Links:\
Hoodi - [https://app.safe.protofire.io](<https://app.safe.protofire.io >)\
Mainnet - <https://app.safe.global/welcome>
{% endhint %}

* [ ] **Browser dApp Wallet** (i.e. Metamask) with 32 Ethers for each validator

<figure><img src="/files/yB0epV8Qy58GprdIYQjM" alt=""><figcaption><p>Example of Vitalik's address in checksum format</p></figcaption></figure>

#### Before continuing please understand the following:

* [ ] The **Withdrawal Address** is:
  * where your ETH is returned upon "voluntary exiting a validator", or also known as full withdrawal.
  * where you receive partial withdrawals, which is where any excess balance above 32 ETH is periodically scraped and made available for use.
* [ ] As this is **permanent** once set, **triple check** your address.
* [ ] DO NOT USE AN :octagonal\_sign: **EXCHANGE ADDRESS** :octagonal\_sign: AS WITHDRAWAL ADDRESS.
* [ ] For **testnet purposes** it's okay to use a browser/hot wallet address.

{% hint style="warning" %}
**Offline Key Generation Best Practices**: The mnemonic seed (24 words) to your validator should be protected by keeping them offline. Use Tails OS (see option 3) or a [Linux Live USB with ethstaker-deposit-cli](https://www.youtube.com/watch?v=oDELXYNSS5w) (Option 1) or Wagyu to generate keys.

If this is not possible, at least physically disconnect from the network by unplugging ethernet cable or disconnecting from Wifi.
{% endhint %}

Ways to create your validator keys:

<details>

<summary>Option 1 for Ubuntu - ethstaker_deposit-cli</summary>

**1. Download ethstaker\_deposit-cli from Github.**

```bash
#Install dependencies
sudo apt install jq curl -y

#Setup variables
RELEASE_URL="https://api.github.com/repos/eth-educators/ethstaker-deposit-cli/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-amd64.tar.gz$)"
BINARY_FILE="ethstaker_deposit-cli.tar.gz"

echo "Downloading URL: $BINARIES_URL"

cd $HOME
#Download binary
wget -O $BINARY_FILE $BINARIES_URL
#Extract archive
tar -xzvf $BINARY_FILE -C $HOME
#Rename
mv ethstaker_deposit*amd64 ethstaker_deposit-cli
cd ethstaker_deposit-cli
```

**2. Make a new mnemonic**

Replace `<HARDWARE_WALLET_ADDRESS>` with withdrawal address.

```
./deposit new-mnemonic --chain hoodi --execution_address <HARDWARE_WALLET_ADDRESS>
```

* Choose your language
* Repeat your withdrawal/execution address for confirmation
* Choose the language of the mnemonic word list
* Choose how many new validators you wish to run
* Create a **keystore password** that secures your validator keystore files
* Repeat your **keystore password** for confirmation
* Answer yes if you want to generate compounding 0x02 validator
* Write down your 24 word mnemonic seed
* Type your mnemonic, first 4 letters is enough

You will see the following messages after successfully generated the keystore(s) and the deposit(s):

```bash

                  #####     #####
                ##     #####     ##
    ###         ##   #######     #########################
    ##  ##      #####               ##                   ##
    ##     #####                 ##                       ##
    ##     ##                     ##                      ###
   ########                        ##                     ####
   ##        ##   ###         #####                       #####
   #                          ##                         # #####
   #                            #                        #  #####
   ##                             ##                    ##
   ##                              ##                   ##
   ##             ###              ##                   ##
   ###############                 ##                   ##
   ###               ##                                 ##
      #############################                    ##
                     ##                             ###
                     #######     #################     ###
                     ##   ## ##        ##   ##    ###
                     ##############          #############

Creating your keys:               [####################################]  <N>/<N>
Creating your keystores:          [####################################]  <N>/<N>
Verifying your keystores:         [####################################]  <N>/<N>
Verifying your deposits:          [####################################]  <N>/<N>

Success!
Your keys can be found at: /home/username/ethstaker_deposit-cli/validator_keys
```

</details>

<details>

<summary>Option 2 for Windows/Linux/Mac - Wagyu GUI</summary>

**Wagyu** is an application aimed at lowering the technical bar to staking on Ethereum.

As a 'one-click installer', it provides a clean UI automating the setup and management of all the infrastructure necessary to stake without the user needing to have any technical knowledge.

**Download Wagyu**: [https://wagyu.gg](https://wagyu.gg/)

1. Click create new secret recovery phrase
2. Select your network
3. Click create
4. Write down your 24 word secret recovery phrase
5. Check your phrase to confirm you copied it correctly
6. Specify number of new keys to generate
7. Specify your keystore password
8. Specify your Withdrawal address
9. Click next
10. Re-type your keystore password
11. Browse to where you want to save your keys
12. Review information and close

</details>

<details>

<summary>Option 3 - Offline Tails with ethstaker_deposit-cli</summary>

You will learn how to boot up a windows PC into an airgapped [Tails operating system](https://tails.boum.org/index.en.html).

The Tails OS is an *amnesic* operating system, meaning it will save nothing and *leave no tracks behind* each time you boot it.

**1. Prerequisites**

You need:

* 2 storage mediums (can be USB stick, SD cards or external hard drives)
* One of them must be > 8GB
* Windows or Mac computer
* 30 minutes or longer depending on your download speed

**2. Download Tails OS**

Download the official image from the [Tails website](https://tails.boum.org/install/index.en.html). Might take a while, go grab a coffee.

Make sure you follow the guide on the Tails website to verify your download of Tails.

**3. Download and install the software to transfer your Tails image on your USB stick**

For Windows, use one of

* [Etcher](https://tails.boum.org/etcher/Etcher-Portable.exe)
* [Win32 Disk Imager](https://win32diskimager.org/#download)
* [Rufus](https://rufus.ie/en_US/)

For Mac, download [Etcher](https://tails.boum.org/etcher/Etcher.dmg)

**4. Making your bootable USB stick**

Run the above software. This is an example how it looks like on Mac OS with etcher, but other software should be similar.

<img src="/files/-MbF9sxqVx2RPyZpErai" alt="" data-size="original">

Select the Tails OS image that you downloaded as the image. Then select the USB stick (the larger one).

Then flash the image to the larger USB stick.

**5. Download and verify the ethstaker\_deposit-cli**

Download the latest ethstaker\_deposit-cli binary by referring to Option 1's steps.

Copy the file to the other USB stick.

**6. Reboot your computer and into Tails OS**

After you have done all the above, you can reboot. If you are connected by a LAN cable to the internet, you can disconnect it manually.

Plug in the USB stick that has your Tails OS.

On Mac, press and hold the Option key immediately upon hearing the startup chime. Release the key after Startup Manager appears.

On Windows, it depends on your computer manufacturer. Usually it is by pressing F1 or F12. If it doesn't work, try googling "Enter boot options menu on \[Insert your PC brand]"

Choose the USB stick that you loaded up with Tails OS to boot into Tails.

**7. Welcome to Tails OS**

<img src="/files/-MbF9vA__yS_1qRPxmPL" alt="" data-size="original">

You can boot with all the default settings.

**8. Run the ethstaker\_deposit-cli**

Plug in your other USB key with the `ethstaker_deposit-cli` file.

Locate the USB key, mount the drive and add execute permissions.

```bash
# Locate the usb key
sudo fdisk -l
# Create a mount point
sudo mkdir -p /media/usb-drive
# Mount the usb key. Change device name
sudo mount /dev/sda1 /media/usb-drive
# Change directories
cd /media/usb-drive/ethstaker_deposit-cli
# Add execute permissions
sudo chmod +x ./deposit
```

**9. Make a new mnemonic**

Replace `<HARDWARE_WALLET_ADDRESS>` with withdrawal address.

```
./deposit new-mnemonic --chain hoodi --execution_address <HARDWARE_WALLET_ADDRESS>
```

* Choose your language
* Repeat your withdrawal/execution address for confirmation
* Choose the language of the mnemonic word list
* Choose how many new validators you wish to run
* Create a **keystore password** that secures your validator keystore files
* Repeat your **keystore password** for confirmation
* Answer yes if you want to generate compounding 0x02 validator
* Write down your 24 word mnemonic seed
* Type your mnemonic, first 4 letters is enough

You will see the following messages after successfully generated the keystore(s) and the deposit(s):

```bash

                  #####     #####
                ##     #####     ##
    ###         ##   #######     #########################
    ##  ##      #####               ##                   ##
    ##     #####                 ##                       ##
    ##     ##                     ##                      ###
   ########                        ##                     ####
   ##        ##   ###         #####                       #####
   #                          ##                         # #####
   #                            #                        #  #####
   ##                             ##                    ##
   ##                              ##                   ##
   ##             ###              ##                   ##
   ###############                 ##                   ##
   ###               ##                                 ##
      #############################                    ##
                     ##                             ###
                     #######     #################     ###
                     ##   ## ##        ##   ##    ###
                     ##############          #############

Creating your keys:               [####################################]  <N>/<N>
Creating your keystores:          [####################################]  <N>/<N>
Verifying your keystores:         [####################################]  <N>/<N>
Verifying your deposits:          [####################################]  <N>/<N>

Success!
Your keys can be found at: /home/username/ethstaker_deposit-cli/validator_keys
```

**Result**: a folder called `validator_keys` containing keystore-m files and deposit\_data.json

If you ran this command directly from your non-Tails USB stick, the validator keys should stay on it.

If it hasn't, copy the directory over to your non-Tails USB stick.

Confirm your validator\_keys are on the USB stick before leaving.

```bash
ls /media/usb-drive/ethstaker_deposit-cli/validator_keys
```

:fire: Make sure you have saved your validator keys directory in your other USB stick (non Tails OS) before you shutdown Tails. Tails will delete everything saved on it after you shutdown.

:tada: Congrats on learning how to use Tails OS to make an air gapped system.

</details>

### Result: There are two types of files generated.

| File type                                                             | Purpose                                                                                                                                                                                                                                        |
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>Keystore file(s)</p><p>\[i.e.. keystore-16945983.json]</p>         | <ul><li>Controls the validator's ability to sign transactions</li><li>Imported and loaded into your validator</li><li>Keep private. Do not share with anyone</li><li>Can be recreated from your mnemonic seed/secret recovery phrase</li></ul> |
| <p>Deposit data file(s)</p><p>\[i.e. deposit\_data-16945983.json]</p> | <ul><li>Public information about your validator</li><li>Required to execute your deposit through the Ethereum Launchpad</li><li>Can be recreated from your mnemonic seed/secret recovery phrase</li></ul>                                      |

## :arrow\_up: 3. Transfer validator keys to node

{% hint style="info" %}
**Local node**: Skip this step if you generated your keys on your node with **ethstaker\_deposit-cli**. No need to transfer as they're already there.
{% endhint %}

After creating the validator keys offline, you'll want to copy these validator keys to your node.

To align with this guide's steps, make the default validator\_keys path on your node.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir -p $HOME/ethstaker_deposit-cli/validator_keys
</strong></code></pre>

To transfer validator key files to your node from your local computer, consider using:

<details>

<summary>Option 1 - File Transfer</summary>

* File transfer
  * Windows OS - use [WinSCP](https://winscp.net) or [FileZilla](https://filezilla-project.org/download.php?type=client)
  * Mac or Linux - use [FileZilla](https://filezilla-project.org/download.php?type=client) or [SFTP](https://www.digitalocean.com/community/tutorials/how-to-use-sftp-to-securely-transfer-files-with-a-remote-server) or [rsync](https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/)

Transfer the **keystore-m\_xxxxxxxx.json** files to the following location on your node.

```bash
$HOME/ethstaker-deposit-cli/validator_keys
```

</details>

<details>

<summary>Option 2 - USB Key</summary>

### **Step 1: From OFFLINE machine, copy validator keys to a USB key.**

Plug the USB key into offline machine, then locate the device name.

```bash
# Locate the usb key
sudo fdisk -l
```

Upon executing the above command you will get an output similar to the one below:

```bash
Disk /dev/sdc: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start      End  Sectors  Size Id Type
/dev/sdc1  *     8192 15555555 25555555 7.4G  b W95 FAT32
```

Mount the key. Change the device name accordingly.

```bash
# Create a mount point
sudo mkdir -p /media/usb-drive
# Mount the usb key
sudo mount /dev/sdc1 /media/usb-drive
```

Copy the keys. Adjust the path names if needed.

```bash
# Create a directory on the usb drive to copy the keys into
sudo mkdir -p /media/usb-drive/ethstaker-deposit-cli/validator_keys
# Copy the keys to the usb drive
sudo cp $HOME/ethstaker-deposit-cli/validator_keys/*.json /media/usb-drive/ethstaker-deposit-cli/validator_keys
# Cleanup
sudo umount /media/usb-drive
```

### **Step 2: From a USB key,  copy validator keys to the NODE.**

Plug the USB key into node, then locate the device name.

```bash
# Locate the usb key
sudo fdisk -l
```

Upon executing the above command you will get an output similar to the one below:

```bash
Disk /dev/sdc: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start      End  Sectors  Size Id Type
/dev/sdc1  *     8192 15555555 25555555 7.4G  b W95 FAT32
```

Mount the key. Change the device name accordingly.

```bash
# Create a mount point
sudo mkdir -p /media/usb-drive
# Mount the usb key
sudo mount /dev/sdc1 /media/usb-drive
```

Copy the keys. Adjust the path names if needed.

```bash
# Create a directory copy the keys into
sudo mkdir -p $HOME/ethstaker-deposit-cli/validator_keys
# Copy the keys to the default path
sudo cp /media/usb-drive/ethstaker-deposit-cli/validator_keys/*.json $HOME/ethstaker-deposit-cli/validator_keys
# Cleanup
sudo umount /media/usb-drive
```

</details>

After transfering the files, verify that the keystore-m files are in the proper location on your node.

```bash
ls -l $HOME/ethstaker_deposit-cli/validator_keys
```

Expected sample output:

```bash
-r--r----- 1 ethereum ethereum 706 Oct  1 02:33 deposit_data-1696645983.json
-r--r----- 1 ethereum ethereum 710 Oct  1 02:33 keystore-m_12381_3600_0_0_0-161664283.json
```

## :woman\_technologist: 4. Deposit transactions at the Launchpad

1. Follow the walk-through at the Launchpad:&#x20;
   * <https://hoodi.launchpad.ethstaker.cc>
   * If you used the #cheap-hoodi-validator method, perform your deposit on [https://cheap.hoodi.launchpad.ethstaker.cc](https://cheap.hoodi.launchpad.ethstaker.cc/)

{% hint style="danger" %}
**Do not send real mainnet ETH during this process!** :octagonal\_sign: Use only Hoodi ETH.
{% endhint %}

2. Upload your`deposit_data-#########.json` found in the `validator_keys` directory.
3. Connect the launchpad with your wallet, review and accept terms. Ensure you're connected to **Hoodi** network.

{% hint style="info" %}
:whale: **Batch Depositing Tip**: If you have many deposits to make for many validators, consider using [Abyss.finance's eth2depositor tool.](https://abyss.finance/eth2depositor) This greatly improves the deposit experience as multiple deposits can be batched into one transaction, thereby saving gas fees and saving your fingers by minimizing Metamask clicking.

On the tool's dropdown box, select **Hoodi** network.

Source: <https://twitter.com/AbyssFinance/status/1379732382044069888>
{% endhint %}

4. Confirm the transaction(s). There's one deposit transaction of 32 ETH (or more for compounding) for each validator.

* **Deposit Example**: If you want to run 3 validators you will need to have (32 x 3) = 96 Hoodi ETH plus some extra to cover the gas fees.
* **Verify Deposit Contract:** Your transaction is depositing your ETH to the Hoodi Deposit Contract address.**Check**, *double-check*, ***triple-check*** that the Hoodi Deposit Contract address is correct. 0x00000000219ab540356cBB839Cbe05303d7705Fa
* **Ledger Nano Hardware wallet users**: If you encounter difficulty making the deposit transaction, enable blind signing and contract data.

## 4. Review backups

{% hint style="danger" %}
:fire: **Critical Crypto Reminder:** **Keep your mnemonics, keep your ETH.**

* **Stay Offline**: Write down your mnemonic seed **offline**. *Not email. Not cloud.*
* **More than 1 backup of mnemonic**: Multiple copies with multiple locations is better. *Best stored in a* [*metal seed.*](https://jlopp.github.io/metal-bitcoin-storage-reviews/)
* **Verify your hardware wallet's backup:** Most important of all data, this is where your withdrawal address belongs and ultimately controls the 32 ETH
* **In case of recovery**: Stored on a USB key, keep copies of
  * `validator_keys directory` - contains all the keystore .json files
  * keystore password - used to encrypt keystore files
    {% endhint %}

#### :tada:Validator key setup and deposits are complete!


# Installing Validator


# Lighthouse

Create a service user for the validator service and create data directories.

```bash
sudo adduser --system --no-create-home --group validator
sudo mkdir -p /var/lib/lighthouse/validators
```

Import your validator keys by importing your **keystore file**. Be sure to enter your **keystore password** correctly.

```bash
sudo lighthouse account validator import \
  --network hoodi \
  --datadir /var/lib/lighthouse \
  --directory=$HOME/ethstaker_deposit-cli/validator_keys \
  --reuse-password
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Verify that your keystore file was imported successfully.

<pre class="language-bash"><code class="lang-bash"><strong>sudo lighthouse account_manager validator list \
</strong><strong>  --network hoodi \
</strong>  --datadir /var/lib/lighthouse
</code></pre>

Once successful, you will be shown your **validator's public key**.

For example, `0x8d9138fcf5676e2031dc4eae30a2c92e3306903eeec83ca83f4f851afbd4cb3b33f710e6f4ac516b4598697b30b04302`

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/lighthouse/validators
sudo chmod 700 /var/lib/lighthouse/validators
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.&#x20;

```bash
[Unit]
Description=Lighthouse Validator Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/lighthouse vc \
  --network hoodi \
  --beacon-nodes http://localhost:5052 \
  --datadir /var/lib/lighthouse \
  --graffiti="🏠🥩🪙🛡️" \
  --metrics \
  --metrics-port 8009 \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a graffiti message that is included when you produce a block, add your message between the double quotes after `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
INFO Enabled validator          voting_pubkey: 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf, signing_method: local_keystore
INFO Enabled validator          voting_pubkey: 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866, signing_method: local_keystore
INFO Initialized validators     enabled: 2, disabled: 0
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Lighthouse Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`INFO Successfully published attestations`".

```
Feb 08 01:01:0 INFO Successfully published attestations type: unaggregated, slot: 12422, committee_index: 3, head_block: 0xabc111daedf1281..., validator_indices: [12345], count:1, service: attestation 
Feb 08 01:01:30 INFO Connected to beacon node(s) synced: 1, available: 1, total: 1, service: notifier
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Lodestar

Setup a Lodestar validator client

Create a service user for the validator service, as this improves security, then create data directories.

<pre class="language-bash"><code class="lang-bash">sudo adduser --system --no-create-home --group validator
<strong>sudo mkdir -p /var/lib/lodestar/validators
</strong></code></pre>

Import your validator keys by importing your **keystore file**. Be sure to enter your **keystore password** correctly.

```bash
cd /usr/local/bin/lodestar
sudo ./lodestar validator import \
  --network hoodi \
  --dataDir="/var/lib/lodestar/validators" \
  --keystore=$HOME/ethstaker_deposit-cli/validator_keys
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Verify that your keystore file was imported successfully.

```bash
sudo ./lodestar validator list \
  --network hoodi \
  --dataDir="/var/lib/lodestar/validators"
```

Once successful, you will be shown your **validator's public key**.

For example, `0x8d9138fcf5676e2031dc4eae30a2c92e3306903eeec83ca83f4f851afbd4cb3b33f710e6f4ac516b4598697b30b04302`

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/lodestar/validators
sudo chmod 700 /var/lib/lodestar/validators
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.

```bash
[Unit]
Description=Lodestar Validator Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=300
WorkingDirectory=/usr/local/bin/lodestar
ExecStart=/usr/local/bin/lodestar/lodestar validator \
  --network hoodi \
  --dataDir /var/lib/lodestar/validators \
  --beaconNodes http://127.0.0.1:5052 \
  --metrics true \
  --metrics.port 8009 \
  --graffiti "🏠🥩🪙🛡️" \
  --suggestedFeeRecipient <0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>
  
[Install]
WantedBy=multi-user.target
```

* Replace\*\*`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`\*\* with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a graffiti message that is included when you produce a block, add your message between the double quotes after `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
info: 100% of local keystores imported. current=2 total=2 rate=975.61keys/m
info: 2 local keystores
info: 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf
info: 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Lodestar Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`info: Published attestations`".

```bash
Feb-1  03:33:30.228     info: Published aggregateAndProofs slot=2662, index=13, count=1
Feb-1  03:37:48.393     info: Published attestations slot=2699, index=20, count=1
Feb-1  03:46:36.450     info: Published attestations slot=2713, index=2, count=1
Feb-1  03:53:48.944     info: Published attestations slot=2765, index=21, count=1
Feb-1  04:01:48.812     info: Published attestations slot=2809, index=17, count=1
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Teku

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Storing your **keystore password** in a text file is required so that Teku can decrypt and load your validators automatically.

Create a temporary file to store your **keystore password**. Type your password in this file.

```bash
sudo nano $HOME/validators-password.txt
```

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Confirm that your **keystore password** is correct.

```bash
sudo cat $HOME/validators-password.txt
```

When specifying directories for your validator-keys, Teku expects to find identically named keystore and password files.

For example `keystore-m_12221_3600_1_0_0-11222333.json` and `keystore-m_12221_3600_1_0_0-11222333.txt`

Run the following command to create a corresponding password file for every one of your validators.

```bash
for f in $HOME/ethstaker_deposit-cli/validator_keys/keystore*.json; do sudo cp $HOME/validators-password.txt $HOME/ethstaker_deposit-cli/validator_keys/$(basename $f .json).txt; done
```

Select a tab for your Teku configuration, either **Standalone Validator (Recommended)** or **Combined Beacon Node with Validator**. Running a standalone validator configuration is recommended for best modularity and redundancy.

{% tabs %}
{% tab title="Standalone Validator (Recommended)" %}
Copy your `validator_keys` to the data directory.

```bash
sudo mkdir -p /var/lib/teku_validator/validator_keys
sudo cp $HOME/ethstaker_deposit-cli/validator_keys/keystore* /var/lib/teku_validator/validator_keys
```

Create a service user for the validator service, then create data directories and setup ownership permissions, including hardening the access to this directory.

```bash
sudo adduser --system --no-create-home --group validator
sudo chown -R validator:validator /var/lib/teku_validator
sudo chmod -R 700 /var/lib/teku_validator
```

Verify that your validator's keystore .json files and validator's passwords .txt files are present by checking the following directory.

```bash
sudo ls -l /var/lib/teku_validator/validator_keys
```

Example output of two validator's keystore.json files with matching password.txt files.

```
-rwx------ 1 validator validator 710 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.json
-rwx------ 1 validator validator  43 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.txt
-rwx------ 1 validator validator 710 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.json
-rwx------ 1 validator validator  43 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.txt
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.&#x20;

```bash
[Unit]
Description=Teku Validator Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/teku/bin/teku validator-client \
  --network=hoodi \
  --data-path=/var/lib/teku_validator \
  --validator-keys=/var/lib/teku_validator/validator_keys:/var/lib/teku_validator/validator_keys \
  --beacon-node-api-endpoint=http://localhost:5052 \
  --validators-proposer-default-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS> \
  --validators-graffiti="🏠🥩🪙🛡️" \
  --metrics-enabled=true \
  --metrics-port=8009

[Install]
WantedBy=multi-user.target
```

* Replac&#x65;**`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>`** with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a short message that is included when you produce a block, add your message to the `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

{% endtab %}

{% tab title="Combined BN+VC" %}
{% hint style="info" %}
**Note**: Teku is configured to run both **validator client** and **beacon chain client** in one process.
{% endhint %}

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R consensus:consensus /var/lib/teku/
sudo chmod -R 700 /var/lib/teku/validator_keys
```

Copy your `validator_keys` to the data directory.

```bash
sudo mkdir -p /var/lib/teku/validator_keys
sudo cp $HOME/ethstaker_deposit-cli/validator_keys/keystore* /var/lib/teku/validator_keys
```

Verify that your validator's keystore .json files and validator's passwords .txt files are present by checking the following directory.

```bash
sudo ls -l /var/lib/teku/validator_keys
```

Example output of two validator's keystore.json files with matching password.txt files.

```
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_1_0_0-1695165818.txt
-rwx------ 1 consensus consensus 710 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.json
-rwx------ 1 consensus consensus  43 Sep 19 23:39 keystore-m_12381_3600_2_0_0-1695165819.txt
```

Finally, restart Teku to use the new validators.

```bash
sudo systemctl restart consensus
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu consensus | ccze
```

{% endtab %}
{% endtabs %}

For example when using 2 validators, logs will show the following:

```bash
INFO  - Loading 2 validator keys...
INFO  - Loaded 2 Validators: 95d3986, 82b225f
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Teku Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`Validator *** Published attestation`".

```bash
teku[65367]: 03:50:51.761 INFO  - Validator cc1f3ade status is active_ongoing.
teku[65367]: 03:50:52.203 INFO  - Validator   *** Published attestation        Count: 1, Slot: 31362, Root: 90FC0DF4D5958E469134A015203B53B3FB94A0FC1038FB2462882906D4A729A2
```

Delete the temporary **keystore password** file.

```bash
sudo rm $HOME/validators-password.txt
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Nimbus

Select a configuration for Nimbus. Running a standalone validator configuration is recommended for best modularity and redundancy.

{% tabs %}
{% tab title="Standalone Validator (Recommended)" %}
Create a service user for the validator service, as this improves security, then create data directories.

<pre class="language-bash"><code class="lang-bash">sudo adduser --system --no-create-home --group validator
<strong>sudo mkdir -p /var/lib/nimbus_validator
</strong></code></pre>

The following command will import your validator keys.

Enter your **keystore password** to import accounts.

```bash
sudo /usr/local/bin/nimbus_beacon_node deposits import \
  --data-dir=/var/lib/nimbus_validator $HOME/ethstaker_deposit-cli/validator_keys
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Now you can verify the accounts were imported successfully by doing a directory listing.

```bash
sudo ls -l /var/lib/nimbus_validator/validators
```

You should see a folder named for each of your validator's pubkey.

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.

```bash
[Unit]
Description=Nimbus Validator Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/nimbus_validator_client \
  --data-dir=/var/lib/nimbus_validator \
  --metrics \
  --metrics-port=8009 \
  --beacon-node=http://127.0.0.1:5052 \
  --graffiti="🏠🥩🪙🛡️" \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>
  
[Install]
WantedBy=multi-user.target
```

* Replace`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a short message that is included when you produce a block, add your message to the `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/nimbus_validator
sudo chmod -R 700 /var/lib/nimbus_validator
```

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

{% endtab %}

{% tab title="Combined (BN+VC)" %}
{% hint style="info" %}
**Note**: In the combined configuration, Nimbus runs both **validator client** and **beacon chain client** in one systemd service process.
{% endhint %}

The following command will import your validator keys.

Enter your **keystore password** to import accounts.

```bash
sudo /usr/local/bin/nimbus_beacon_node deposits import \
  --data-dir=/var/lib/nimbus $HOME/staking-deposit-cli/validator_keys
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Now you can verify the accounts were imported successfully by doing a directory listing.

```bash
sudo ls -l /var/lib/nimbus/validators
```

You should see a folder named for each of your validator's pubkey.

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R consensus:consensus /var/lib/nimbus
sudo chmod -R 700 /var/lib/nimbus
```

Finally, restart Nimbus to use the new validators.

```bash
sudo systemctl restart consensus
```

Check your logs to confirm that the validators are up and functioning.

```bash
sudo journalctl -fu consensus | ccze
```

{% endtab %}
{% endtabs %}

For example when using 2 validators, logs will show the following:

```bash
Loading validators             topics="beacval" validatorsDir=/var/lib/nimbus/validators keystore_cache_available=true
Local validator attached       topics="val_pool" pubkey=95d39860a0d6ea3b92cba78069d21f3a validator=95d39860 initial_fee_recipient=81ba8d5c4ae850
Local validator attached       topics="val_pool" pubkey=82b225f66476962b161ed015786df00f validator=82b225f6 initial_fee_recipient=81ba8d5c4ae850
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Nimbus Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`Attestation sent`".

```bash
nimbus_beacon_node[292966]: INF 2023-02-05 01:25:26.263+00:00 Attestation sent      attestation="(aggregation_bits: 0b00000000000000000000000000000000000000000000000000000000, data: (slot: 31235, index: 3, beacon_block_root: \"ca3213f1\", source: \"1901:9deza1289\", target: \"1901:6ab1fafff\"), signature: \"32173064\")" delay=46ms543us294ns subnet_id=20
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Prysm

Create a service user for the validator service, as this improves security, then create data directories.

<pre class="language-bash"><code class="lang-bash">sudo adduser --system --no-create-home --group validator
<strong>sudo mkdir -p /var/lib/prysm/validators
</strong></code></pre>

Storing your **keystore password** in a text file is required so that Prysm can decrypt and load your validators automatically.

Create a file to store your **keystore password**. Type your password in this file.

<pre class="language-bash"><code class="lang-bash"><strong>sudo nano /var/lib/prysm/validators/password.txt
</strong></code></pre>

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Confirm that your **keystore password** is correct.

```bash
sudo cat /var/lib/prysm/validators/password.txt
```

Import your validator keys by importing your **keystore file**. When asked to create a new wallet password, enter your **keystore password**. When prompted for the imported accounts password, enter your **keystore password** again.

```bash
sudo /usr/local/bin/validator accounts import \
  --accept-terms-of-use \
  --hoodi \
  --wallet-dir=/var/lib/prysm/validators \
  --keys-dir=$HOME/ethstaker_deposit-cli/validator_keys
```

{% hint style="danger" %}
WARNING: Do not import your validator keys into multiple validator clients and run them at the same time, or you might get slashed. If moving validators to a new setup or different validator client, ensure deletion of the previous validator keys before continuing.
{% endhint %}

Verify that your keystore file was imported successfully.

<pre class="language-bash"><code class="lang-bash"><strong>sudo /usr/local/bin/validator accounts list \
</strong>  --wallet-dir=/var/lib/prysm/validators \
  --hoodi
</code></pre>

Once successful, you will be shown your **validator's public key**. For example:

```
Showing 2 validator accounts
View the eth1 deposit transaction data for your accounts by running `validator accounts list --show-deposit-data`

Account 0 | gently-learning-chamois
[validating public key] 0x95d39860a0d6ea3b92cba78069d21f3a987988f3b8417b14f0945353d79ed9e338bbe6e9d63d487abc044a710ce34866

Account 1 | presumably-powerful-lynx
[validating public key] 0x82b225f66476962b161ed015786df00a0b7b28231915e6d09e81ba8d5c4ae8502b6d5337e3bf101ad72741dc69f0a7cf
```

Setup ownership permissions, including hardening the access to this directory.

```bash
sudo chown -R validator:validator /var/lib/prysm/validators
sudo chmod 700 /var/lib/prysm/validators
```

Create a **systemd unit file** to define your `validator.service` configuration.

```bash
sudo nano /etc/systemd/system/validator.service
```

Paste the following configuration into the file.

```bash
[Unit]
Description=Prysm Validator Client service for Hoodi
Wants=network-online.target
After=network-online.target
Documentation=https://www.coincashew.com

[Service]
Type=simple
User=validator
Group=validator
Restart=on-failure
RestartSec=3
KillSignal=SIGINT
TimeoutStopSec=900
ExecStart=/usr/local/bin/validator \
  --hoodi \
  --accept-terms-of-use \
  --datadir=/var/lib/prysm/validators \
  --beacon-rpc-provider=localhost:4000 \
  --beacon-rpc-gateway-provider=localhost:5052 \
  --wallet-dir=/var/lib/prysm/validators \
  --wallet-password-file=/var/lib/prysm/validators/password.txt \
  --graffiti="🏠🥩🪙🛡️" \
  --monitoring-port=8009 \
  --suggested-fee-recipient=<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>

[Install]
WantedBy=multi-user.target
```

* Replace`<0x_CHANGE_THIS_TO_MY_ETH_FEE_RECIPIENT_ADDRESS>` with your own Ethereum address that you control. Tips are sent to this address and are immediately spendable.
* If you wish to customize a graffiti message that is included when you produce a block, add your message between the double quotes after `--graffiti`. Maximum length is 16 characters.

To exit and save, press `Ctrl` + `X`, then `Y`, then `Enter`.

Run the following to enable auto-start at boot time.

```bash
sudo systemctl daemon-reload
sudo systemctl enable validator
```

Finally, start your validator client and check it's status.

```bash
sudo systemctl start validator
sudo systemctl status validator
```

Check your logs to confirm that the validator clients are up and functioning.

```bash
sudo journalctl -fu validator | ccze
```

For example when using 2 validators, logs will show the following:

```bash
level=info msg="Validating for public key" prefix=validator publicKey=0x95d39860a0d6
level=info msg="Validating for public key" prefix=validator publicKey=0x82b225f66476
```

Press `Ctrl` + `C` to exit the logs.

**Example of Synced Prysm Validator Client Logs**

* Once the validator is active and proceeded through the validator activation queue, attestation messages will appear indicating successful attestations.
* Notice the key words "`INFO validator: Submitted new attestations`".

```bash
[2022-11-21 1:21:21]  INFO validator: Submitted new attestations AggregatorIndices=[12412] AttesterIndices=[73613] BeaconBlockRoot=0xca3213f1a3 CommitteeIndex=12 Slot=12422 SourceEpoch=12318 SourceRoot=0xd9ddeza1289 TargetEpoch=121231 TargetRoot=0xff313419acaa1
```

#### Cleanup leftover validator\_keys <a href="#optional-step-0-cleanup-leftover-validator_keys" id="optional-step-0-cleanup-leftover-validator_keys"></a>

Verify that you have backups of validator\_keys directory. The contents are the keystore files.

Having backup copies of your validator\_keys directory on USB media can make recovery from node problems quicker. Validator keys can always be regenerated from secret recovery mnemonic phrase.

You may safely delete the directory.

```bash
# Remove default validator_key directory
sudo rm -r $HOME/ethstaker_deposit-cli/validator_keys
```


# Next Steps

{% hint style="success" %}
:tada: Congrats! You've finished the primary steps of setting up your validator. You're now an Ethereum staker!
{% endhint %}

## :track\_next: FAQ

<details>

<summary>Wen staking rewards?</summary>

**Activation Queue**: Once your EL+CL is synced, validator up and running, you just wait for activation. This process can take 24+ hours. Only 900 new validators can join per day. Check the queue length: [https://wenmerge.com ](<https://wenmerge.com >)

**Activated**: When you're activated, your validator will begin creating and voting on blocks while earning staking rewards.

**Quick monitoring**: Use <https://hoodi.beaconcha.in> to create alerts and track your validator's performance.

</details>

<details>

<summary>Sync Timeline</summary>

Syncing the consensus client is instantaneous with checkpoint sync but the execution client can take up to a day. On nodes with fast NVME drives and gigabit internet, expect your node to be fully synced in a few hours.

**How do I know I'm fully synced?**

* Check your execution client's logs and compare the block number against the most recent block on <https://hoodi.etherscan.io>
  * Check EL logs: `journalctl -fu execution`
* Thanks to checkpoint sync, your consensus client's is instantly synched. You can compare the slot number against the most recent slot on <https://hoodi.beaconcha.in>
  * Check CL logs: `journalctl -fu consensus`

</details>

### :thumbsup: Recommended Steps

* :rocket: **Install** [**EthPillar**](/coins/overview-eth/ethpillar):  your node's buddy for easy and fast node management! Update your software with a keystroke.

#### :arrow\_forward: EthPillar Quickstart: Ubuntu One-liner Install <a href="#quickstart-ubuntu-one-liner-install" id="quickstart-ubuntu-one-liner-install"></a>

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

* :newspaper2:**Subscribe to your Execution Client and Consensus Client's Github repository**: Be notified of new releases. Find the Github links on each EL/CL's Overview section. At your EL or CL's github page while logged in, click the **Watch** button > **Custom** > click the checkbox for "**Release**".
* :smile:**Join Community**: Join the [community on Discord and Reddit](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/joining-the-community-on-discord-and-reddit#discord) to discuss all things staking related.
* :tools:**Node** **Maintenance**: Familiarize yourself with [Part II - Maintenance](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-ii-maintenance) section, as you'll need to keep your staking node running at its best.
* :books:**Study** [**EthStaker Knowledge Base**](https://docs.ethstaker.cc/ethstaker-knowledge-base/): Increase your staking understanding
* :cd:**Backups**: Review your staking validator backups!
* :fingers\_crossed:**Finished testing?** Before decommissioning your validator, it's good practice to properly [exit your validator](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/voluntary-exiting-a-validator) as this improves staking network health.

### :checkered\_flag: Optional Steps

* :robot:**MEV-boost**: Setup [MEV-boost](/coins/overview-eth/mev-boost) for extra staking rewards!
* :bar\_chart:**Monitoring**: Setup [Monitoring with Grafana and Prometheus](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/monitoring-your-validator-with-grafana-and-prometheus)
* :chains:**RPC**: Setup using your own [Node as a RPC endpoint](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/using-staking-node-as-rpc-url-endpoint).
* :mobile\_phone:**Notifications**: Setup [Mobile App Notifications and Monitoring by beaconcha.in](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/mobile-app-node-monitoring-by-beaconchain)
* :up:**External Monitoring**: Setup [External Monitoring with Uptime Check by Google Cloud](/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/monitoring-with-uptime-check-by-google-cloud)
* :books:**Knowledge**: Familiarize yourself with [Part III - Tips](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips) section, as you dive deeper into staking.

### :telephone: **Need extra live support?**

* Find Ethstaker frens on the [Ethstaker](https://discord.io/ethstaker) Discord and [coincashew](https://discord.gg/dEpAVWgFNB) Discord.
* Use reddit: [r/Ethstaker](https://www.reddit.com/r/ethstaker/), or [DMs](https://www.reddit.com/user/coincashew), or [r/coincashew](https://www.reddit.com/r/coincashew/)

### :heart\_decoration: Like these guides?

* **Audience-funded guide**: If you found this helpful, [please consider supporting it directly.](/donations) :pray:
* **Support us on Gitcoin Grants:** We build this guide exclusively by community support!
* **Feedback or pull-requests**: <https://github.com/coincashew/coincashew>

{% hint style="success" %}

#### Ready for mainnet staking? [**Mainnet guide available here.**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet)

{% endhint %}

## Last Words

> I stand upon the shoulders of giants and as such, invite you to stand upon mine. Use my work with or without attribution; I make no claim of "intellectual property." My ideas are the result of countless millenia of evolution - they belong to humanity.

<figure><img src="/files/uuUrHLVnTHEwjAQYS54Y" alt=""><figcaption><p>This is Leslie, the official mascot of Eth Staking</p></figcaption></figure>


# Maintenance


# Updating Execution Client

## :rocket: Automated Updates

:pill:**Install** [**EthPillar**](/coins/overview-eth/ethpillar): a simple companion UI for node management!&#x20;

Update your software with a keystroke.

To update, navigate to

`EthPillar > Execution Client > Update to latest release`

<figure><img src="/files/V3wTRIHTLu9ivOhCZLKC" alt=""><figcaption><p>EthPillar Update</p></figcaption></figure>

## :fast\_forward: Manual Updates

When a new release is cut, you will want to update to the latest stable release. The following shows you how to update your execution client.

{% hint style="warning" %}
Always review the **release notes** before updating. There may be changes requiring your attention.

* [Nethermind](https://github.com/NethermindEth/nethermind/releases)
* [Besu](https://github.com/hyperledger/besu/releases)
* [Geth](https://github.com/ethereum/go-ethereum/releases)
* [Erigon](https://github.com/ledgerwatch/erigon/releases)
* [Reth](https://github.com/paradigmxyz/reth)
  {% endhint %}

## Step 1: Select your execution client.

{% hint style="info" %}
**Did you know you can use** [**EthPillar**](/coins/overview-eth/ethpillar)**?**<br>

:rocket: [**EthPillar**](/coins/overview-eth/ethpillar):  your node's buddy for easy and fast node management! Update your software with a keystroke.<br>

#### :arrow\_forward: EthPillar Quickstart: Ubuntu One-liner Install <a href="#quickstart-ubuntu-one-liner-install" id="quickstart-ubuntu-one-liner-install"></a>

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

{% endhint %}

### Nethermind

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-zip and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/NethermindEth/nethermind/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux-x64)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O nethermind.zip $BINARIES_URL
unzip -o nethermind.zip -d $HOME/nethermind
rm nethermind.zip
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/nethermind
sudo mv $HOME/nethermind /usr/local/bin/nethermind
sudo systemctl start execution
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/nethermind
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
dotnet publish src/Nethermind/Nethermind.Runner -c release -o nethermind
```

Verify Nethermind was properly built by checking the version.

```shell
./nethermind/nethermind --version
```

Sample output of a compatible version.

```
Version: 1.25.2+78c7bf5f
Commit: 78c7bf5f2c0819f23e248ee6d108c17cd053ffd3
Build Date: 2024-01-23 06:34:53Z
OS: Linux x64
Runtime: .NET 8.0.1
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/nethermind
sudo mv $HOME/git/nethermind/nethermind /usr/local/bin
sudo systemctl start execution
```

</details>

### Besu

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/hyperledger/besu/releases/latest"
TAG=$(curl -s $RELEASE_URL | jq -r .tag_name)
BINARIES_URL="https://github.com/hyperledger/besu/releases/download/$TAG/besu-$TAG.tar.gz"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O besu.tar.gz $BINARIES_URL
tar -xzvf besu.tar.gz -C $HOME
rm besu.tar.gz
sudo mv $HOME/besu-${TAG} besu
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/besu
sudo mv $HOME/besu /usr/local/bin/besu
sudo systemctl start execution
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/besu
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
./gradlew installDist
```

Verify Besu was properly built by checking the version.

```shell
./build/install/besu/bin/besu --version
```

Sample output of a compatible version.

```
besu/v23.4.0/linux-x86_64/openjdk-java-17
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/besu
sudo cp -a $HOME/git/besu/build/install/besu /usr/local/bin/besu
sudo systemctl start execution
```

</details>

### Geth

<details>

<summary>Option 1 - Download binaries</summary>

<pre class="language-bash"><code class="lang-bash">RELEASE_URL="https://geth.ethereum.org/downloads"
<strong>FILE="https://gethstore.blob.core.windows.net/builds/geth-linux-amd64[a-zA-Z0-9./?=_%:-]*.tar.gz"
</strong>BINARIES_URL="$(curl -s $RELEASE_URL | grep -Eo $FILE | head -1)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O geth.tar.gz $BINARIES_URL
tar -xzvf geth.tar.gz -C $HOME --strip-components=1
</code></pre>

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Install new binaries, restart the services and cleanup files.

```bash
sudo mv $HOME/geth /usr/local/bin
sudo systemctl start execution
rm geth.tar.gz COPYING
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binary.

```bash
cd $HOME/git/go-ethereum
# Get new tags
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build
make geth
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/geth
sudo cp $HOME/git/go-ethereum/build/bin/geth /usr/local/bin
sudo systemctl start execution
```

</details>

### Erigon

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

<pre class="language-bash"><code class="lang-bash">RELEASE_URL="https://api.github.com/repos/erigontech/erigon/releases/latest"
<strong>BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep linux_amd64.tar.gz)"
</strong>
echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O erigon.tar.gz $BINARIES_URL
tar -xzvf erigon.tar.gz -C $HOME
mv erigon_* erigon
</code></pre>

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/erigon
sudo mv $HOME/erigon/erigon /usr/local/bin/erigon
sudo systemctl start execution
rm -rf erigon/ erigon.tar.gz
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binary.

```bash
cd $HOME/git/erigon
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
make erigon
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/erigon
sudo cp $HOME/git/erigon/build/bin/erigon /usr/local/bin
sudo systemctl start execution
```

</details>

### Reth

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/paradigmxyz/reth/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r '.assets[] | select(.name | startswith ("reth")) | .browser_download_url' | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
wget -O reth.tar.gz $BINARIES_URL
tar -xzvf reth.tar.gz -C $HOME
rm reth.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries, display the version, and restart the services.

```bash
sudo rm -rf /usr/local/bin/reth
sudo mv $HOME/reth /usr/local/bin
reth --version
sudo systemctl restart execution
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/reth
git fetch --tags
# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
# Checkout latest tag
git checkout $latestTag
# Build the release
cargo build --release --features jemalloc
```

Verify Reth was built properly by checking the version number.

```bash
~/git/reth/target/release/reth --version
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
cargo build --release --features jemalloc
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop execution
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/reth
sudo cp ~/git/reth/target/release/reth /usr/local/bin
sudo systemctl restart execution
```

</details>

## Step 2: Verify services and logs are working properly

```bash
# Verify services status
sudo systemctl status execution
```

```bash
# Check logs
sudo journalctl -fu execution
```

## Step 3: Optional - Verify your validator's attestations on public block explorer

1\) Visit [https://holesky.beaconcha.in](https://holesky.beaconcha.in/)

2\) Enter your validator's pubkey into the search bar and look for successful attestations.


# Updating Consensus Client

Scenario: In discord, you see an alert that your consensus client just announced a new release. How best to update?

## :rocket: Automated Updates

:pill:**Install** [**EthPillar**](/coins/overview-eth/ethpillar): a simple companion UI for node management!&#x20;

Update your software with a keystroke.

To update, navigate to

`EthPillar > Consensus Client > Update to latest release`

<figure><img src="/files/NVpfKft5gehiXZ5eznlx" alt=""><figcaption><p>EthPillar Update</p></figcaption></figure>

## :fast\_forward: Manual Updates

When a new release is cut, you will want to update to the latest stable release. The following shows you how to update your beacon chain and validator.

{% hint style="warning" %}
Always review the **release notes** before updating. There may be changes requiring your attention.

* [Lighthouse](https://github.com/sigp/lighthouse/releases)
* [Lodestar](https://github.com/ChainSafe/lodestar/releases)
* [Teku](https://github.com/ConsenSys/teku/releases)
* [Nimbus](https://github.com/status-im/nimbus-eth2/releases)
* [Prysm](https://github.com/prysmaticlabs/prysm/releases)
  {% endhint %}

## Step 1: Select your consensus client.

{% hint style="info" %}
**Did you know you can use** [**EthPillar**](/coins/overview-eth/ethpillar)**?**<br>

:rocket: [**EthPillar**](/coins/overview-eth/ethpillar):  your node's buddy for easy and fast node management! Update your software with a keystroke.<br>

#### :arrow\_forward: EthPillar Quickstart: Ubuntu One-liner Install <a href="#quickstart-ubuntu-one-liner-install" id="quickstart-ubuntu-one-liner-install"></a>

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/coincashew/EthPillar/main/install.sh)"
```

{% endhint %}

### Lighthouse

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/sigp/lighthouse/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep x86_64-unknown-linux-gnu.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lighthouse.tar.gz $BINARIES_URL
# Untar
tar -xzvf lighthouse.tar.gz -C $HOME
# Cleanup
rm lighthouse.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

<pre class="language-bash"><code class="lang-bash">sudo rm /usr/local/bin/lighthouse
<strong>sudo mv $HOME/lighthouse /usr/local/bin/lighthouse
</strong><strong>sudo systemctl start consensus validator
</strong></code></pre>

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Build the binaries.

```bash
cd ~/git/lighthouse
git fetch --all && git checkout stable && git pull
make
```

:bulb:**Tip**: Improve some Lighthouse benchmarks by around 20% at the expense of increased compile time? Use `maxperf` profile.

* To compile with maxperf, replace the above `make` command with

```bash
PROFILE=maxperf make
```

In case of compilation errors, run the following sequence.

```bash
rustup update
cargo clean
make
```

Verify lighthouse was built properly by checking the version number.

```
lighthouse --version
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo rm /usr/local/bin/lighthouse
</strong><strong>sudo cp $HOME/.cargo/bin/lighthouse /usr/local/bin/lighthouse
</strong>sudo systemctl start consensus validator
</code></pre>

</details>

### Lodestar

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ChainSafe/lodestar/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://github.com/ChainSafe/lodestar/releases/download/${LATEST_TAG}/lodestar-${LATEST_TAG}-linux-amd64.tar.gz"
	
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O lodestar.tar.gz $BINARIES_URL
# Untar
tar -xzvf lodestar.tar.gz -C $HOME
# Cleanup
rm lodestar.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/lodestar && sudo mkdir -p /usr/local/bin/lodestar
sudo mv $HOME/lodestar /usr/local/bin/lodestar
sudo systemctl start consensus validator
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Pull the latest source and build Lodestar.

```bash
cd ~/git/lodestar
git checkout stable && git pull
yarn install
yarn run build
```

:warning: In case of build errors or missing dependencies, run the following command.

```bash
yarn clean:nm && yarn install
```

Verify Lodestar was installed properly by displaying the version.

```bash
./lodestar --version
```

Sample output of a compatible version.

```
🌟 Lodestar: TypeScript Implementation of the Ethereum Consensus Beacon Chain.
  * Version: v1.8.0/stable/a4b29cf
  * by ChainSafe Systems, 2018-2022
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/lodestar
sudo cp -a $HOME/git/lodestar /usr/local/bin/lodestar
sudo systemctl start consensus validator
```

</details>

### Teku

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/ConsenSys/teku/releases/latest"
LATEST_TAG="$(curl -s $RELEASE_URL | jq -r ".tag_name")"
BINARIES_URL="https://artifacts.consensys.net/public/teku/raw/names/teku.tar.gz/versions/${LATEST_TAG}/teku-${LATEST_TAG}.tar.gz"
echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O teku.tar.gz $BINARIES_URL
# Untar
tar -xzvf teku.tar.gz -C $HOME
# Rename folder
mv teku-${LATEST_TAG} teku
# Cleanup
rm teku.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus
</strong><strong>
</strong># If running Standalone Teku Validator
sudo systemctl stop validator
</code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/teku
sudo mv $HOME/teku /usr/local/bin/teku
sudo systemctl start consensus

# If running Standalone Teku Validator
sudo systemctl start validator
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Fetch the latest tags and build the binaries.

```bash
cd ~/git/teku
# Get new tags
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/ConsenSys/teku/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
./gradlew distTar installDist
```

Verify Teku was built properly by displaying the version.

```shell
cd $HOME/git/teku/build/install/teku/bin
./teku --version
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus
</strong><strong>
</strong># If running Standalone Teku Validator
sudo systemctl stop validator
</code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm -rf /usr/local/bin/teku
sudo cp -a $HOME/git/teku/build/install/teku /usr/local/bin/teku
sudo systemctl start consensus

# If running Standalone Teku Validator
sudo systemctl start validator
```

</details>

### Nimbus

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest linux release, un-tar and cleanup.

```bash
RELEASE_URL="https://api.github.com/repos/status-im/nimbus-eth2/releases/latest"
BINARIES_URL="$(curl -s $RELEASE_URL | jq -r ".assets[] | select(.name) | .browser_download_url" | grep _Linux_amd64.*.tar.gz$)"

echo Downloading URL: $BINARIES_URL

cd $HOME
# Download
wget -O nimbus.tar.gz $BINARIES_URL
# Untar
tar -xzvf nimbus.tar.gz -C $HOME
# Rename folder
mv nimbus-eth2_Linux_amd64_* nimbus
# Cleanup
rm nimbus.tar.gz
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus
</strong># If running standalone Nimbus Validator
<strong>sudo systemctl stop validator
</strong></code></pre>

Remove old binaries, install new binaries, cleanup and restart the services.

```bash
sudo rm /usr/local/bin/nimbus_beacon_node
sudo rm /usr/local/bin/nimbus_validator_client
sudo mv nimbus/build/nimbus_beacon_node /usr/local/bin
sudo mv nimbus/build/nimbus_validator_client /usr/local/bin
rm -r nimbus
sudo systemctl start consensus
# If running standalone Nimbus Validator
sudo systemctl start validator
```

Reminder: In combined CL+VC Nimbus configuration, there will be no validator systemctl service.

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Pull the latest source code and build the binary.

<pre class="language-bash"><code class="lang-bash">cd ~/git/nimbus-eth2
git checkout stable &#x26;&#x26; git pull
make -j$(nproc) update
<strong>make -j$(nproc) nimbus_beacon_node
</strong>make -j$(nproc) nimbus_validator_client
</code></pre>

Verify Nimbus was built properly by displaying the version.

```bash
cd $HOME/git/nimbus-eth2/build
./nimbus_beacon_node --version
```

Stop the services.

```bash
sudo systemctl stop consensus
# If running standalone Nimbus Validator
sudo systemctl stop validator
```

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm /usr/local/bin/nimbus_beacon_node
sudo rm /usr/local/bin/nimbus_validator_client
sudo cp $HOME/git/nimbus-eth2/build/nimbus_beacon_node /usr/local/bin
sudo cp $HOME/git/nimbus-eth2/build/nimbus_validator_client /usr/local/bin
sudo systemctl start consensus
# If running standalone Nimbus Validator
sudo systemctl start validator
```

Reminder: In combined CL+VC Nimbus configuration, there will be no validator systemctl service.

</details>

### Prysm

<details>

<summary>Option 1 - Download binaries</summary>

Run the following to automatically download the latest binaries.

```bash
cd $HOME
prysm_version=$(curl -f -s https://prysmaticlabs.com/releases/latest)
file_beacon=beacon-chain-${prysm_version}-linux-amd64
file_validator=validator-${prysm_version}-linux-amd64
curl -f -L "https://prysmaticlabs.com/releases/${file_beacon}" -o beacon-chain
curl -f -L "https://prysmaticlabs.com/releases/${file_validator}" -o validator
chmod +x beacon-chain validator
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm /usr/local/bin/beacon-chain
sudo rm /usr/local/bin/validator
sudo mv beacon-chain validator /usr/local/bin
sudo systemctl start consensus validator
```

</details>

<details>

<summary>Option 2 - Build from source code</summary>

Pull the latest source code and build the binaries.

```bash
cd $HOME/git/prysm
git fetch --tags
RELEASETAG=$(curl -s https://api.github.com/repos/OffchainLabs/prysm/releases/latest | jq -r .tag_name)
git checkout tags/$RELEASETAG
go build -o=./build/beacon-chain ./cmd/beacon-chain
go build -o=./build/validator ./cmd/validator
```

Stop the services.

<pre class="language-bash"><code class="lang-bash"><strong>sudo systemctl stop consensus validator
</strong></code></pre>

Remove old binaries, install new binaries and restart the services.

```bash
sudo rm /usr/local/bin/beacon-chain
sudo rm /usr/local/bin/validator
sudo cp $HOME/git/prysm/build/beacon-chain /usr/local/bin
sudo cp $HOME/git/prysm/build/validator /usr/local/bin
sudo systemctl start consensus validator
```

</details>

## Step 2: Verify services and logs are working properly

{% tabs %}
{% tab title="Lighthouse | Prysm | Lodestar | Nimbus | Teku" %}

```bash
# Verify services status
sudo systemctl status consensus validator
```

```bash
# Check logs
sudo journalctl -fu consensus
```

```bash
sudo journalctl -fu validator
```

{% endtab %}

{% tab title=" Combined BN+VC for Nimbus | Teku" %}

```bash
# Check services status
sudo systemctl status consensus 
```

```bash
# Check logs
sudo journalctl -fu consensus
```

{% endtab %}
{% endtabs %}

## Step 3: Optional - Verify your validator's attestations on public block explorer

1\) Visit [https://holesky.beaconcha.in](https://holesky.beaconcha.in/)

2\) Enter your validator's pubkey into the search bar and look for successful attestations.


# Backups Checklist: Critical Staking Node Data

{% hint style="info" %}
Annually, it's good practice to review and refamilarize yourself that your staking data is backed up and accessible.
{% endhint %}

{% hint style="danger" %}
:fire: **Critical Crypto Reminder:** **Keep your mnemonics, keep your ETH.**

* **Withdrawal Wallet Seed Phrase**: Ideally this is secured by a hardware wallet. Most important piece of data and represents your ETH!
* **Validator Key Mnemonic**: Write this down **offline**. Not email. Not cloud.
* **Validator\_keys directory**: Contains keystore files and deposit\_data.
* **Password for keystore files:** Required when installing validators.

**Suggestions**:

* Create multiple copies. *Best stored in a* [*metal seed.*](https://jlopp.github.io/metal-bitcoin-storage-reviews/)
* Make **offline backups**, such as to a USB key, of your **`validator_keys`** directory.
  {% endhint %}


# Uninstalling Staking Node

{% hint style="info" %}
Whether changing clients for client diversity purposes, moving to a new node, or retiring a staking node, here's how to uninstall the three key components of a staking node.
{% endhint %}

### Uninstalling execution client&#x20;

```bash
sudo systemctl stop execution
sudo systemctl disable execution
sudo rm /etc/systemd/system/execution.service

#Nethermind
sudo rm -rf /usr/local/bin/nethermind
sudo rm -rf /var/lib/nethermind

#Besu
sudo rm -rf /usr/local/bin/besu
sudo rm -rf /var/lib/besu

#Geth
sudo rm -rf /usr/local/bin/geth
sudo rm -rf /var/lib/geth

#Erigon
sudo rm -rf /usr/local/bin/erigon
sudo rm -rf /var/lib/erigon

#Reth
sudo rm -rf /usr/local/bin/reth
sudo rm -rf /var/lib/reth

sudo userdel execution
```

### Uninstalling consensus client&#x20;

```bash
sudo systemctl stop consensus
sudo systemctl disable consensus
sudo rm /etc/systemd/system/consensus.service

#Lighthouse
sudo rm -rf /usr/local/bin/lighthouse
sudo rm -rf /var/lib/lighthouse

#Lodestar
sudo rm -rf /usr/local/bin/lodestar
sudo rm -rf /var/lib/lodestar

#Teku
sudo rm -rf /usr/local/bin/teku
sudo rm -rf /var/lib/teku

#Nimbus
sudo rm -rf /usr/local/bin/nimbus_beacon_node
sudo rm -rf /var/lib/nimbus

#Prysm
sudo rm -rf /usr/local/bin/beacon-chain
sudo rm -rf /var/lib/prysm

sudo userdel consensus
```

### Uninstalling validator

```bash
sudo systemctl stop validator
sudo systemctl disable validator
sudo rm /etc/systemd/system/validator.service

#Lighthouse
sudo rm -rf /var/lib/lighthouse/validators

#Lodestar
sudo rm -rf /var/lib/lodestar/validators

#Teku, if running Standalone Teku Validator
sudo rm -rf /var/lib/teku_validator

#Nimbus, if running standalone Nimbus Validator
sudo rm -rf /var/lib/nimbus_validator
sudo rm -rf /usr/local/bin/nimbus_validator_client

#Prysm
sudo rm -rf /usr/local/bin/validator
sudo rm -rf /var/lib/prysm/validators

sudo userdel validator
```


# Guide | How to setup a validator for Ethereum staking on testnet HOLESKY

Using the gold standard of ETH staking, become a solo home staker. Help decentralize Ethereum, a proof-of-stake blockchain. Anyone with 32 ETH can join.

## Installation

### :rocket:Option 1: Quickstart with EthPillar

* Recommended for most users.
* In minutes, rapidly deploys a systemd installation with minority clients Nimbus CL Nethermind EL and mevboost.
* Supports automated node deployment for both validators and non-staking RPC nodes.
* When EthPillar is deployed, operating your node becomes a breeze.

To install EthPillar, [visit the quickstart page.](/coins/overview-eth/ethpillar)

<figure><img src="/files/HCFPqea9Z5MktcDDPTvQ" alt=""><figcaption><p>EthPillar's TUI - Navigate the menu to control your node</p></figcaption></figure>

### :chains:Option 2: Manual Installation

* This guide aims to reduce the reliance on scripts in this section to make the learning process more straightforward and understandable.
* This approach provides a detailed overview of the steps involved, ensuring stakers have a clear understanding of the process.
* Great for advanced users comfortable with the CLI terminal who want full control and require customization of EL/CL combinations and their configurations.
* Deploys a systemd installation with any EL/CL combination you choose.
* After installation, use [EthPillar](/coins/overview-eth/ethpillar) to simplify maintenance of your node.

To install manually, continue with this guide.

#### :shield: Built by home-stakers for home-stakers. :pray:


# Overview - Manual Installation

## :new: Announcements

{% hint style="success" %}
As of July 6 2024, this **Version 2 Guide** written for **🦉Dencun**🦉 **Holesky Testnet** :grin:
{% endhint %}

{% hint style="info" %}
:sparkles:**Always test and practice on testnet first.** [**Mainnet guide available here.**](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet)
{% endhint %}

## :wrench: About This Guide

For the advanced user who wants customization and is comfortable with CLI commands, this guide will walk you through the details of setting up a validator. For most users, the quickest and automated way to setup a staking node is with [EthPillar](/coins/overview-eth/ethpillar).

## :thumbsup: Your Github Contributions Welcome

This guide is fully open source and fully powered by home-stakers like you.

Pull requests or issues can be submitted on [github](https://github.com/coincashew/coincashew).

{% embed url="<https://github.com/coincashew/coincashew>" %}

#### :arrow\_up: [View Changelog](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/changelog): See the latest changes to the guide.


# Step 1: Prerequisites

## :rocket: How Staking on Ethereum Works

1. Acquire some hardware (laptop, desktop, server) or rent a VPS (cloud server): You need to run a node to stake.
2. Sync an execution layer client
3. Sync a consensus layer client
4. Generate your validator keys and import them into your validator client
5. Monitor and maintain your node

A Ethereum node consists of the Execution Layer + Consensus Layer.

A Ethereum Staking node is the previous plus a Validator client.

<figure><img src="/files/s1oKZXCcrZioRrPAMkps" alt=""><figcaption><p>Client Stack</p></figcaption></figure>

<figure><img src="/files/gY9TruKmwgL2Jn9yFe1U" alt=""><figcaption><p>Big picture: Execution / Consensus / Validator</p></figcaption></figure>

## :wave: Introduction

This guide was written for aspiring Ethereum stakers who have basic familiarity with command line tools and it was tested against Ubuntu 22.04.1 LTS client. You’ll want a dedicated cloud VPS or local desktop/server/laptop running a clean install of Ubuntu preferably.

### Terminology

Your Ethereum staking node may be

* **Local:** on a laptop / PC / NUC that you can physically connect keyboard/mouse/monitor.
* **Remote:** in the cloud on a VPS

If your staking node is **remote**, then you will want to setup SSH, secure shell.

If using a VPS or **remote** node, install and start the SSH client for your operating system:

**Windows**: [PuTTY](https://www.puttygen.com/download-putty)

**MacOS and Linux**: from the Terminal, use the native command:

```
ssh <YourUserName>@<YourServersIP>
```

Here's a [guide from Makeuseof](https://www.makeuseof.com/tag/beginners-guide-setting-ssh-linux-testing-setup/) to connect by SSH to your **remote node.**

## :hammer\_pick: How to Run Commands

* Commands are to be run in a terminal window or ssh terminal.
* Commands preceded by `sudo` will prompt for your password at first, and periodically afterwards.

## :woman\_technologist: Skills for operating an staking node

As a validator for Ethereum, you will typically have the following abilities:

* operational knowledge of how to set up, run and maintain a Ethereum consensus client, execution client and validator continuously
* a long term commitment to maintain your validator 24/7/365
* basic operating system skills

## :man\_technologist: Experience required to be a successful ETH Staker

* have studied [Ethstaker's Staking for Beginners](https://www.reddit.com/r/ethstaker/wiki/staking_for_beginners/)
* have perused the vast tomes of the [EthStaker Knowledge Base](https://docs.ethstaker.cc/ethstaker-knowledge-base/)

## :man\_lifting\_weights: Recommended Node Setup Requirements

* **Operating system:** Ubuntu 24.04 LTS Server or Desktop
* **Processor:** 4 CPU Cores or more
* **Memory:** 32GB RAM
* **Storage:** Testnet: 300GB. Mainnet: 4TB NVME (not QLC).
* **Internet:** Stable broadband internet connections with speeds at least 20 Mbps without data limit.
* **Data Plan**: At least 2 TB per month. Ideally, no data cap or unlimited data plan.
* **Power:** Reliable electrical power with a [Uninterruptible Power Supply (UPS)](https://www.lifewire.com/best-uninterrupted-power-supplies-4142625).
* **ETH balance:** 2.4ETH for [Lido CSM](https://csm.testnet.fi/?ref=ethpillar) or at least 32 ETH for solo staking with 1 validator
* **Wallet**: [Rabby](https://rabby.io/) Wallet installed

{% hint style="info" %}
:desktop: **Hardware Builds**: For examples of actual staking hardware builds, check out [RocketPool's hardware guide](https://github.com/rocket-pool/docs.rocketpool.net/blob/main/docs/guides/node/local/hardware.md#example-setups) and [Ethstaker's Hardware Examples](https://docs.ethstaker.cc/ethstaker-knowledge-base/hardware/hardware-examples).
{% endhint %}

{% hint style="info" %}
:cd: **Storage Suggestion**: Check out the following to find your ideal NVME or SSD drive.

* [**Yorick's Storage Advice**](https://gist.github.com/yorickdowne/f3a3e79a573bf35767cd002cc977b038): Refer to Yorick's Great and less great SSDs for Ethereum nodes
* [**Top SSD List**](https://docs.google.com/spreadsheets/d/1B27_j9NDPU3cNlj2HKcrfpJKHkOf-Oi1DbuuQva2gT4/edit)**:** Suitable drives are identified as Mid-Range or better.
  {% endhint %}

<figure><img src="/files/X2z463D8wsbAfaAYxeJg" alt=""><figcaption><p>Ethereum Staking Node</p></figcaption></figure>

{% hint style="success" %}
:sparkles: **Pro Validator Tip**: Highly recommend you begin with a brand new instance of an OS, VM, and/or machine. Avoid headaches by NOT reusing testnet keys, wallets, or databases for your validator.
{% endhint %}

## :desktop: Local Node vs Remote Node

**Decision**: Do I run my Ethereum staking node locally at home or rent a VPS cloud server remotely? Here's a list of criteria to help you decide.

|       Criteria       | Local Node                                                                                                                                         | Remote Node                                                                                                                                                                 |
| :------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|     Ongoing Costs    | Plus - No fees, besides internet bill and electricity.                                                                                             | Minus - Monthly or Annual reoccurring rental fees.                                                                                                                          |
| Hardware Maintenance | Minus - Do it yourself if hardware issues.                                                                                                         | Plus - Included, covered by hosting provider.                                                                                                                               |
|       Internet       | Minus - Can slow down home internet and use up data plan (if not unlimited) Budget for at least 2TB per month data plan.                           | Plus - Often plans are generous and more than sufficient for an ETH node.                                                                                                   |
|      Reliability     | Minus - Do it yourself with UPS, redundant internet connections, computer issues                                                                   | Plus - Hosted in a data center with multiple power/internet backups.                                                                                                        |
|   Barrier to Entry   | <p>Plus - Can re-use or re-purpose existing hardware<br><br>Minus - Initial cost to purchase new computer equipment</p>                            | Plus - Renting a VPS might require a lower initial investment as you can pay monthly.                                                                                       |
|   Decentralization   | Plus - Home staking is the **gold standard** for Ethereum decentralization, nothing bets it!                                                       | Minus - VPS cloud hosts like [Netcup](https://www.netcup.eu/bestellen/produkt.php?produkt=3026) or AmazonWebServices are by nature more centralized.                        |
|     Customization    | Plus - More fine control over hardware configuration                                                                                               | Minus - May be limited choices and hardware can be shared. For example, a common issue is insufficient disk storage I/O speeds (IOPS).                                      |
|       Security       | Plus - As secure as your home and personal [OPSEC](https://en.wikipedia.org/wiki/Operations_security)                                              | <p>Plus - Enterprise-grade, professional data centers.</p><p>Minus - Not your hardware, not your node. It's possible the hosting provide can view your node's contents.</p> |
|        Freedom       | <p>Plus - Do whatever you want. Plan your own upgrades.<br><br>Minus - With great freedom and power, you are solely responsible for your node.</p> | <p>Plus - Professionally managed.</p><p><br>Minus - At the mercy of the host's actions, data center outages are possible.</p>                                               |

## :tools: Setup Ubuntu

With your local or remote node, now you need to install an Operating System. This guide is designed for Ubuntu 22.04.1 LTS.

* To install **Ubuntu Server or Desktop**, refer to this [guide](https://docs.ethstaker.cc/ethstaker-knowledge-base/tutorials/installing-linux).

{% hint style="info" %}
**Recommendation**: A headless (no monitor) install of **Ubuntu Server** on a **dedicated** NUC/laptop/desktop/VPS is best for ease of reliability and security. :fire: Do not use this system for email/browsing web/gaming/socials. :fire:
{% endhint %}

{% hint style="warning" %}
**Tip**: When installing Ubuntu Server, ensure you are selecting “**Use an entire disk**” on the **Guided storage configuration** screen. Next screen will be the **Storage configuration** screen, ensure your settings are using all available disk storage. A [common issue](/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-iii-tips/using-all-available-lvm-disk-space) is that Ubuntu server defaults to using only 200GB.
{% endhint %}

## :performing\_arts: Setup Rabby

When the time comes to make your validator's 32ETH deposit(s), you'll need a wallet to transfer funds to the beacon chain deposit contract.

* To install Rabby, visit their [official site.](https://rabby.io/)

## :jigsaw: High Level Validator Node Overview

{% hint style="info" %}
At the end of this guide, you will build a staking validator node that hosts three main components in two layers: consensus layer consists of a consensus client, also known as a validator client with a beacon chain client. The execution layer consists of a execution client, formerly a eth1 node.

**Validator client** - Responsible for producing new blocks and attestations in the beacon chain and shard chains.

**Consensus client** - Responsible for managing the state of the beacon chain, validator shuffling, and more.

**Execution client** - Supplies incoming validator deposits from the eth mainnet chain to the beacon chain client.
{% endhint %}

![How Ethereum nodes fits together featuring Leslie the Rhino, the mascot named after American computer scientist Leslie Lamport](/files/-MPCDQuE1PFqzrv0AzuT)




---

[Next Page](/llms-full.txt/1)

