Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add script to generate blsToExecutionChange for testnet validators. #167

Merged
merged 10 commits into from
Apr 20, 2023
53 changes: 38 additions & 15 deletions local-testnet/README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
# Simple Local Testnet

These scripts allow for running a small local testnet with multiple beacon nodes and validator clients.
These scripts allow for running a small local testnet with multiple beacon nodes and validator clients and a geth execution client.
This setup can be useful for testing and development.

## Requirements

The scripts require `lcli` and `lighthouse` to be installed on `PATH`. From the
The scripts require `lcli`, `lighthouse`, `geth`, `bootnode` to be installed on `PATH`. From the
root of this repository, run:

```bash
make
make install-lcli
```

### MacOS Users

Install GNU `sed` and GNU `grep`, and add them both to `PATH`, e.g.

```
brew install gnu-sed grep
echo "export PATH=\$(brew --prefix)/opt/grep/libexec/gnubin:$PATH" >> ~/.bash_profile
echo "export PATH=\$(brew --prefix)/opt/gnu-sed/libexec/gnubin:$PATH" >> ~/.bash_profile
```

## Starting the testnet

Modify `vars.env` as desired.

Start a local eth1 ganache server plus boot node along with `BN_COUNT`
number of beacon nodes and `VC_COUNT` validator clients.
The testnet starts with a post-merge genesis state.
Start a consensus layer and execution layer boot node along with `BN_COUNT`
number of beacon nodes each connected to a geth execution client and `VC_COUNT` validator clients.

The `start_local_testnet.sh` script takes four options `-v VC_COUNT`, `-d DEBUG_LEVEL`, `-p` to enable builder proposals and `-h` for help. It also takes a mandatory `GENESIS_FILE` for initialising geth's state.
A sample `genesis.json` is provided in this directory.

The `ETH1_BLOCK_HASH` environment variable is set to the block_hash of the genesis execution layer block which depends on the contents of `genesis.json`. Users of these scripts need to ensure that the `ETH1_BLOCK_HASH` variable is updated if genesis file is modified.

The `start_local_testnet.sh` script takes three options `-v VC_COUNT`, `-d DEBUG_LEVEL` and `-h` for help.
The options may be in any order or absent in which case they take the default value specified.
- VC_COUNT: the number of validator clients to create, default: `BN_COUNT`
- DEBUG_LEVEL: one of { error, warn, info, debug, trace }, default: `info`



```bash
./start_local_testnet.sh
./start_local_testnet.sh genesis.json
```

## Stopping the testnet
Expand All @@ -41,31 +57,38 @@ This is not necessary before `start_local_testnet.sh` as it invokes `stop_local_

These scripts are used by ./start_local_testnet.sh and may be used to manually

Start a local eth1 ganache server
```bash
./ganache_test_node.sh
```

Assuming you are happy with the configuration in `vars.env`, deploy the deposit contract, make deposits,
Assuming you are happy with the configuration in `vars.env`, deploy the deposit contract,
create the testnet directory, genesis state and validator keys with:

```bash
./setup.sh
```

Generate bootnode enr and start a discv5 bootnode so that multiple beacon nodes can find each other
Note: The generated genesis validators are embedded into the genesis state as genesis validators and hence do not require manual deposits to activate.

Generate bootnode enr and start an EL and CL bootnode so that multiple nodes can find each other
```bash
./bootnode.sh
./el_bootnode.sh
```

Start a geth node:
```bash
./geth.sh <DATADIR> <NETWORK-PORT> <HTTP-PORT> <AUTH-HTTP-PORT> <GENESIS_FILE>
```
e.g.
```bash
./geth.sh $HOME/.lighthouse/local-testnet/geth_1 5000 6000 7000 genesis.json
```

Start a beacon node:

```bash
./beacon_node.sh <DATADIR> <NETWORK-PORT> <HTTP-PORT> <OPTIONAL-DEBUG-LEVEL>
./beacon_node.sh <DATADIR> <NETWORK-PORT> <HTTP-PORT> <EXECUTION-ENDPOINT> <EXECUTION-JWT-PATH> <OPTIONAL-DEBUG-LEVEL>
```
e.g.
```bash
./beacon_node.sh $HOME/.lighthouse/local-testnet/node_1 9000 8000
./beacon_node.sh $HOME/.lighthouse/local-testnet/node_1 9000 8000 http://localhost:6000 ~/.lighthouse/local-testnet/geth_1/geth/jwtsecret
```

In a new terminal, start the validator client which will attach to the first
Expand Down
15 changes: 12 additions & 3 deletions local-testnet/beacon_node.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#/usr/bin/env bash
#!/usr/bin/env bash

#
# Starts a beacon node based upon a genesis state created by `./setup.sh`.
Expand Down Expand Up @@ -30,6 +30,8 @@ while getopts "d:sh" flag; do
echo " DATADIR Value for --datadir parameter"
echo " NETWORK-PORT Value for --enr-udp-port, --enr-tcp-port and --port"
echo " HTTP-PORT Value for --http-port"
echo " EXECUTION-ENDPOINT Value for --execution-endpoint"
echo " EXECUTION-JWT Value for --execution-jwt"
exit
;;
esac
Expand All @@ -39,14 +41,19 @@ done
data_dir=${@:$OPTIND+0:1}
network_port=${@:$OPTIND+1:1}
http_port=${@:$OPTIND+2:1}
execution_endpoint=${@:$OPTIND+3:1}
execution_jwt=${@:$OPTIND+4:1}

exec lighthouse \
lighthouse_binary=lighthouse

exec $lighthouse_binary \
--debug-level $DEBUG_LEVEL \
bn \
$SUBSCRIBE_ALL_SUBNETS \
--datadir $data_dir \
--testnet-dir $TESTNET_DIR \
--enable-private-discovery \
--disable-peer-scoring \
--staking \
--enr-address 127.0.0.1 \
--enr-udp-port $network_port \
Expand All @@ -57,4 +64,6 @@ exec lighthouse \
--http-port $http_port \
--disable-packet-filter \
--target-peers $((BN_COUNT - 1)) \
--gui
--gui \
--execution-endpoint $execution_endpoint \
--execution-jwt $execution_jwt
2 changes: 1 addition & 1 deletion local-testnet/clean.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash

#
# Deletes all files associated with the local testnet.
Expand Down
2 changes: 1 addition & 1 deletion local-testnet/dump_logs.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash

# Print all the logs output from local testnet

Expand Down
3 changes: 3 additions & 0 deletions local-testnet/el_bootnode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
priv_key="02fd74636e96a8ffac8e7b01b0de8dea94d6bcf4989513b38cf59eb32163ff91"
source ./vars.env
$EL_BOOTNODE_BINARY --nodekeyhex $priv_key
14 changes: 0 additions & 14 deletions local-testnet/ganache_test_node.sh

This file was deleted.

74 changes: 74 additions & 0 deletions local-testnet/generate_bls_to_execution_change.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
#
# This script generates a BLS to execution change for given validator indices on the local testnet.
#
# Prerequisites: jq, docker

source ./vars.env

# The index position for the keys to start generating withdrawal credentials in ERC-2334 format.
VALIDATOR_START_INDEX=$1
# Comma separated list of validator indices to use, e.g. 0,1,2
VALIDATOR_INDICES=$2
# The execution (Eth1) address you want to change to for withdrawals.
EXECUTION_ADDRESS=$3
BEACON_API_URL='http://localhost:8001'

function print_help() {
echo ""
echo "Usage:"
echo "$0 <VALIDATOR_START_INDEX> <VALIDATOR_INDICES> <EXECUTION_ADDRESS>"
echo ""
echo "Example:"
echo "$0 0 0,1,2 0x49011adbCC3bC9c0307BB07F37Dda1a1a9c69d2E"
}

vars=("GENESIS_FORK_VERSION" "MNEMONIC_PHRASE")
for varname in "${vars[@]}"; do
if [ -z "${!varname}" ]; then
echo "Error: Variable $varname is not set. Please set it in vars.env" >&2
exit 1
fi
done

args=("VALIDATOR_START_INDEX" "VALIDATOR_INDICES" "EXECUTION_ADDRESS")
for argname in "${args[@]}"; do
if [ -z "${!argname}" ]; then
echo "Error: $argname is not set." >&2
print_help
exit 1
fi
done

genesis_validators_root=$(curl -s $BEACON_API_URL/eth/v1/beacon/genesis | jq -r .data.genesis_validators_root)

if [[ -z "$genesis_validators_root" ]]; then
echo "Error: genesis_validators_root not found. Make sure the beacon chain is started correctly." >&2
exit 1
fi

echo "Generating BLS to execution change for validators: $VALIDATOR_INDICES"

validator_withdrawal_credentials_list=()
for index in $(echo "$VALIDATOR_INDICES" | tr ',' ' '); do
withdrawal_credentials=$(curl -s $BEACON_API_URL/eth/v1/beacon/states/head/validators | jq -r ".data[] | select(.index == \"$index\") | .validator.withdrawal_credentials")
validator_withdrawal_credentials_list+=($withdrawal_credentials)
echo "Validator $index withdrawal credentials: $withdrawal_credentials"
done

# Convert the array to a comma separated list
validator_withdrawal_credentials_list=$(IFS=, ; echo "${validator_withdrawal_credentials_list[*]}")
devnet_chain_setting="{\"network_name\": \"local\", \"genesis_fork_version\": \"$GENESIS_FORK_VERSION\", \"genesis_validator_root\": \"$genesis_validators_root\"}"

docker run -it --rm -v $(pwd)/bls_to_execution_changes:/app/bls_to_execution_changes ethereum/staking-deposit-cli \
--language English \
--non_interactive \
generate-bls-to-execution-change \
--chain mainnet \
--devnet_chain_setting "$devnet_chain_setting" \
--validator_start_index "$VALIDATOR_START_INDEX" --validator_indices "$VALIDATOR_INDICES" \
--bls_withdrawal_credentials_list "$validator_withdrawal_credentials_list" \
--mnemonic "$MNEMONIC_PHRASE" \
--execution_address "$EXECUTION_ADDRESS"

echo "BLS to execution change generated in bls_to_execution_changes directory."
Loading