# How to run a node on the Holesky testnet? ## Who is this guide for? This guide is meant to be a starting point and provides a mid-level summary of the required steps. It is not intended to be a beginner's guide, so copying and running commands from here may not work without some tweaking. The testnet is meant to mimic a chain that is post-merge. Therefore, the genesis state will be in a merged state. The chain will have to go through a the shapella fork at epoch 256. The JSON-RPC endpoint, faucet, and other tooling URLs can be found on https://holesky.ethpandaops.io/ ## Which version/branch do I use? #### Consensus layer | Client Name | Version | Docker image | |--- |--- |--- | | Lighthouse | [4.5.0+](https://github.com/sigp/lighthouse/releases/tag/v4.5.0) | sigp/lighthouse:4.5.0 | | Teku | [23.9.1+](https://github.com/Consensys/teku/releases/tag/23.9.1) | consensys/teku:23.9.1 | | Lodestar | [v1.11.3+](https://github.com/chainsafe/lodestar/releases/tag/v1.11.3) | chainsafe/lodestar:1.11.3 | | Prysm | [4.1.0-alpha.1+](https://github.com/prysmaticlabs/prysm/releases/tag/v4.1.0-alpha.1) | gcr.io/prysmaticlabs/prysm/beacon-chain:v4.1.0-alpha.1, gcr.io/prysmaticlabs/prysm/validator:v4.1.0-alpha.1 | | Nimbus | [23.9.1+](https://github.com/status-im/nimbus-eth2/releases/tag/23.9.1) | ethpandaops/nimbus:23.9.1 | #### Execution layer | Client Name | Git Branch | Docker image | |--- |--- |--- | | Geth | [1.13.2+](https://github.com/ethereum/go-ethereum/releases/tag/v1.13.2) | ethereum/client-go:v1.13.2 | | Nethermind | [1.20.4+](https://github.com/NethermindEth/nethermind/releases/tag/1.20.4) | nethermind/nethermind:1.20.4 | | Besu | [23.7.3+](https://github.com/hyperledger/besu/releases/tag/23.7.3) | hyperledger/besu:23.7.3 | | Erigon | [2.49.3](https://github.com/ledgerwatch/erigon/releases/tag/v2.49.3) | thorax/erigon:v2.49.3 | | EthereumJS | - | - | | Reth | [v0.1.0-alpha.10](https://github.com/paradigmxyz/reth/releases/tag/v0.1.0-alpha.10) | - | ## Preparation Generate the JWT secret with openssl ```shell= openssl rand -hex 32 | tr -d "\n" > "/tmp/jwtsecret" ``` This file needs to be passed to both the Execution Client and the Consensus Client. If you do not specify a JWT secret, then the execution and/or consensus layer client will automatically generate one for you. You will then have to specify this secret in the Consensus Layer client. # Run an Execution Layer Client ## Geth Pre-requisites: `git, make, go, gcc`. Clone and build the `master` branch of [Geth](https://github.com/ethereum/go-ethereum) ```shell= git clone https://github.com/ethereum/go-ethereum.git cd go-ethereum make geth cd .. ``` From the `custom_config_data` folder start the client ```shell= # Run geth ./go-ethereum/build/bin/geth \ --datadir "geth-datadir" \ --http --http.api="engine,eth,web3,net,debug" \ --ws --ws.api="engine,eth,web3,net,debug" \ --http.corsdomain "*" \ --holesky \ --syncmode=full \ --authrpc.jwtsecret=/tmp/jwtsecret ``` ## Nethermind Pre-requisites: `git, dotnet` Please ensure you have Node 12.x+ installed. Clone and build the `master` branch of [Nethermind](https://github.com/NethermindEth/nethermind/) ```shell= git clone https://github.com/NethermindEth/nethermind.git cd nethermind/src/Nethermind dotnet build Nethermind.sln -c Release ``` From the `custom_config_data/nethermind/src/Nethermind/` folder start the client ```shell= cd Nethermind.Runner dotnet run -c Release -- \ --config=holesky \ --datadir="../../../../nethermind-datadir" \ --JsonRpc.Host=0.0.0.0 \ --JsonRpc.JwtSecretFile=/tmp/jwtsecret ``` ## Besu Pre-requisites: `git, jvm` Clone and build the `master` branch of [Besu](https://github.com/hyperledger/besu) ```shell= git clone --recursive https://github.com/hyperledger/besu cd besu ./gradlew installDist cd .. ``` From the `custom_config_data` folder start the client ```shell= besu/build/install/besu/bin/besu \ --network=holesky \ --data-path="besu-datadir" \ --rpc-http-enabled=true \ --rpc-http-host="0.0.0.0" \ --rpc-http-cors-origins="*"\ --rpc-ws-enabled=true \ --rpc-ws-host="0.0.0.0" \ --host-allowlist="*" \ --engine-host-allowlist="*"\ --engine-jwt-enabled=true \ --engine-jwt-secret=/tmp/jwtsecret \ --data-storage-format=BONSAI ``` ## EthereumJS Pre-requisites: `git, node, npm` Please ensure you have [Node 18.x+](https://github.com/nodesource/distributions/blob/master/README.md) installed. Clone and build from source ```shell= git clone --depth 1 https://github.com/ethereumjs/ethereumjs-monorepo.git cd ethereumjs-monorepo npm i ``` From the `custom_config_data` folder start the client ```shell= cd packages/client npm run client:start -- \ --datadir ../../../ethereumjs-datadir \ --network=holesky \ --saveReceipts \ --rpc \ --rpcport=8545 \ --jwt-secret=/tmp/jwtsecret \ --rpcEngine \ --rpcEnginePort=8551 ``` This will create a secret in ethereumjs-datadir/jwtsecret, you will need to provide this secret to the CL client. ## Erigon Pre-requisites: `git, go` Clone and build from source develop branch of [Erigon](https://github.com/ledgerwatch/erigon) ```shell= git clone https://github.com/ledgerwatch/erigon cd erigon make erigon rpcdaemon cd .. ``` From the `custom_config_data` folder start the client ```shell= # Run Erigon ./erigon/build/bin/erigon \ --datadir erigon-datadir \ --chain=holesky \ --authrpc.jwtsecret=/tmp/jwtsecret \ --http --http.api=engine,net,eth ``` ## Reth Pre-requisites: `git,rust` Please ensure you have [RustC 1.59.x+](https://rustup.rs) installed. Clone and build from source ```shell= git clone https://github.com/paradigmxyz/reth.git cd reth make install ``` From the `custom_config_data` folder start the client ```shell= cargo run node \ --datadir reth-datadir \ --chain holesky --authrpc.jwtsecret=/tmp/jwtsecret \ --http ``` # Execution layer conclusions After starting the client, you will be able to interact with the client using the following ports: * localhost:8545: Web3 json rpc * localhost:8550: Engine json rpc * localhost:8551: Engine json rpc with json rpc authentication * jwt.hex in the repository where you ran the rpcdaemon: verification key for JWT authentication # Run a Consensus Layer Client and Validators ## Lighthouse Pre-requisites: `git, rust` Please ensure you have [RustC 1.59.x+](https://rustup.rs) installed. Clone and build from source ```shell= git clone https://github.com/sigp/lighthouse.git cd lighthouse make cd .. ``` From the `custom_config_data` folder start the client ```shell= lighthouse \ bn \ --datadir=lighthouse-datadir \ --eth1 \ --http \ --network=holesky \ --http-allow-sync-stalled \ --execution-endpoints=http://127.0.0.1:8551 \ --enr-udp-port=9000 \ --enr-tcp-port=9000 \ --discovery-port=9000 \ --jwt-secrets="/tmp/jwtsecret" \ --suggested-fee-recipient=<enter-eth-address-here> #If validators enabled ``` To import validator keys to a validator client from `custom_config_data`: ```shell= lighthouse \ account validator import \ --datadir=lighthouse-datadir/validator-data \ --directory=<path/to/validator_keys> ``` To start the validator client from `custom_config_data` ```shell= lighthouse \ vc \ --network=holesky \ --datadir=lighthouse-datadir/validator-data \ --suggested-fee-recipient=<enter-eth-address-here> ``` ## Lodestar Pre-requisites: `git, nodejs, yarn` More info about how to install dependencies can be found [here](https://chainsafe.github.io/lodestar/install/source/) Clone and build the client ```shell= git clone https://github.com/chainsafe/lodestar.git cd lodestar yarn install --ignore-optional yarn run build ``` From the `custom_config_data/lodestar` folder start the client ```shell= ./lodestar beacon \ --network=holesky \ --dataDir="../lodestar-datadir" \ --execution.urls="http://127.0.0.1:8551" \ --jwt-secret="/tmp/jwtsecret" \ --eth1.depositContractDeployBlock=0 \ --suggestedFeeRecipient=<enter-eth-address-here> #If validators enabled ``` To import the validator keys from `custom_config_data/lodestar` and enter the password you used to generate the keystore file: ```shell= ./lodestar validator import \ --dataDir="../lodestar-datadir/validator-data" \ --importKeystores="<path/to/validator_keys>" ``` To run a validator: ```shell= ./lodestar validator \ --paramsFile="../config.yaml" \ --dataDir="../lodestar-datadir/validator-data" \ --keystoresDir="../lodestar-datadir/validator-data/keystores" \ --secretsDir="../lodestar-datadir/validator-data/secrets" \ --suggestedFeeRecipient=<enter-eth-address-here> ``` ## Teku Pre-requisites: `git, java` Ensure Java 11 or above is installed (Ubuntu: sudo apt install default-jre). ```shell= git clone https://github.com/ConsenSys/teku.git cd teku ./gradlew installDist cd .. ``` The teku executable is now available in ./teku/build/install/teku/bin/teku. You can also use the pre-built distribution or the consensys/teku:develop docker image. From the `custom_config_data` folder start the client ```shell= ./teku/build/install/teku/bin/teku \ --data-path="teku-datadir" \ --network=holesky \ --ee-endpoint="http://localhost:8551" \ --ee-jwt-secret-file="/tmp/jwtsecret" \ --validator-keys="<path/to/validator/keys>:</path/to/validator/secrets>" \ #If validators enabled --validators-proposer-default-fee-recipient=<Enter-eth-address-here> #If validators enabled ``` ## Prysm Pre-requisites: `git, bazel` Ensure bazel 5.3.+ is [installed](https://docs.prylabs.network/docs/install/install-with-bazel#install-bazel-using-bazelisk). ```shell= mkdir -p prysm-dir export genesis=$PWD/genesis.ssz export prysmdir=$PWD/prysm-datadir export config=$PWD/config.yaml git clone https://github.com/prysmaticlabs/prysm.git cd prysm bazel build //cmd/beacon-chain:beacon-chain ``` From the `custom_config_data/prysm` folder start the beaconchain client ```shell= bazel run //cmd/beacon-chain -- \ --accept-terms-of-use=true \ --holesky \ --datadir=$prysmdir \ --execution-endpoint=http://localhost:8551 \ --jwt-secret=/tmp/jwtsecret \ --suggested-fee-recipient=<Enter-eth-address-here> #If validators enabled ``` To import validator keys: ```shell= bazel run //validator:validator -- accounts import \ --accept-terms-of-use \ --wallet-dir=$prysmdir/validator-data \ --keys-dir=<path/to/validator/keys> ``` To start the validator client, make sure you have created a secret file (containing with your secret info in) and call it `prysm-dir/validator-data/secret.txt`. Then it will not prompt you at each startup. ```shell= bazel run //cmd/validator -- \ --accept-terms-of-use=true \ --holesky \ --datadir=$prysmdir \ --beacon-rpc-provider=http://localhost:4000 \ --wallet-dir=$prysmdir/validator-data \ --wallet-password-file=$prysmdir/validator-data/secret.txt \ --suggested-fee-recipient=<Enter-eth-address-here> ``` ## Nimbus Pre-requisites: `git, make, gcc` Ensure that the websocket related flags (--ws) are present on your EL (e.g: Geth). Nethermind enables websockets by default. Nimbus can use either http or ws. Clone and build from source (use branch unstable) ```shell= git clone https://github.com/status-im/nimbus-eth2.git cd nimbus-eth2 make update make -j4 nimbus_beacon_node cd .. ``` Start the beaconchain client ```shell= nimbus-eth2/build/nimbus_beacon_node \ --data-dir=./nimbus-datadir\ --jwt-secret=/tmp/jwtsecret \ --web3-url=http://127.0.0.1:8551 \ --rest \ --network=holesky \ --suggested-fee-recipient=<Enter-eth-address-here> #If validators enabled ``` Import your validator keys: ```shell= nimbus-eth2/build/nimbus_beacon_node deposits import \ --data-dir=nimbus-datadir \ <path/to/validator/keys> ``` Now restart your nimbus with the same command as when you first time started, and the validator keys will be loaded up already. It is also possible to have a separate validator process for nimbus. More info on how to do this can be found [here](https://nimbus.guide/validator-client.html). {%hackmd theme-dark %} <style> .markdown-body pre {background-color: #1E1E1E;border: 1px solid #555 !important;color: #73BCE0;border-radius:8px;/*border-radius:0px;*/ } .markdown-body pre .htmlembedded {color: #C8D4C8 !important; } .markdown-body pre .hljs-tag {color: #6D726E; } .markdown-body pre .token.keyword {color: #C586C0; } .markdown-body pre .token.string, .markdown-body pre .hljs-string {color: #C68362; } .markdown-body pre .hljs-comment, .markdown-body pre .token.comment {color: #6A9955; } .markdown-body pre .hljs-attr {color: #73BCE0; } .markdown-body pre .hljs-name {color:#569CD6; } .markdown-body pre .token.operator {color:#C8D4C8;background:transparent; } .markdown-body pre .token.property {color: #73BCE0; } .markdown-body pre .token.function {color: #DCDCAA; } .markdown-body pre .token.builtin {color: #34B294; } .markdown-body pre .token.number {color: #B5CEA8; } .markdown-body pre .token.constant {color: #3BC1FF; } .markdown-body pre .hljs-addition {color: #96D47D;background: #373D29; } .markdown-body pre .hljs-deletion {color: #E76A6A;background: #4B1818; } .markdown-body pre .hljs-selector-class {color: #D7BA5F; } .markdown-body pre .hljs-attribute {color: #9CDCFE; } .markdown-body pre .hljs-number {color: #C68362; } .markdown-body pre .hljs-meta {color: #2C7CD6; } </style>