Create a local testnet (#2614)

The testnet will be on the local computer and have 1 eth1 node,
4 beacon nodes, 1 validator with 20 vc's.
This commit is contained in:
Wink Saville 2021-10-01 06:32:37 +00:00
parent ea78315749
commit 21d1af435a
8 changed files with 231 additions and 26 deletions

View File

@ -15,6 +15,32 @@ make install-lcli
## 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 `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
```
## Stopping the testnet
This is not necessary before `start_local_testnet.sh` as it invokes `stop_local_testnet.sh` automatically.
```bash
./stop_local_testnet.sh
```
## Manual creation of local testnet
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
@ -59,13 +85,13 @@ You can create additional beacon node and validator client instances with approp
### Adjusting number and distribution of validators
The `VALIDATOR_COUNT` parameter is used to specify the number of insecure validator keystores to generate and make deposits for.
The `NODE_COUNT` parameter is used to adjust the division of these generated keys among separate validator client instances.
For e.g. for `VALIDATOR_COUNT=80` and `NODE_COUNT=4`, the validator keys are distributed over 4 datadirs with 20 keystores per datadir. The datadirs are located in `$DATADIR/node_{i}` which can be passed to separate validator client
The `BN_COUNT` parameter is used to adjust the division of these generated keys among separate validator client instances.
For e.g. for `VALIDATOR_COUNT=80` and `BN_COUNT=4`, the validator keys are distributed over 4 datadirs with 20 keystores per datadir. The datadirs are located in `$DATADIR/node_{i}` which can be passed to separate validator client
instances using the `--datadir` parameter.
### Starting fresh
Delete the current testnet and all related files using:
Delete the current testnet and all related files using. Generally not necessary as `start_local_test.sh` does this each time it starts.
```bash
./clean.sh
@ -82,6 +108,5 @@ Update the genesis time to now using:
./reset_genesis_time.sh
```
> Note: you probably want to drop the beacon node database and the validator
> client slashing database if you do this. When using small validator counts
> it's probably easy to just use `./clean.sh && ./setup.sh`.
> Note: you probably want to just rerun `./start_local_testnet.sh` to start over
> but this is another option.

View File

@ -1,25 +1,54 @@
#!/usr/bin/env bash
#
# Starts a beacon node based upon a genesis state created by
# `./setup.sh`.
# Starts a beacon node based upon a genesis state created by `./setup.sh`.
#
# Usage: ./beacon_node.sh <DATADIR> <NETWORK-PORT> <HTTP-PORT> <OPTIONAL-DEBUG-LEVEL>
source ./vars.env
DEBUG_LEVEL=${4:-info}
SUBSCRIBE_ALL_SUBNETS=
DEBUG_LEVEL=${DEBUG_LEVEL:-info}
# Get options
while getopts "d:sh" flag; do
case "${flag}" in
d) DEBUG_LEVEL=${OPTARG};;
s) SUBSCRIBE_ALL_SUBNETS="--subscribe-all-subnets";;
h)
echo "Start a beacon node"
echo
echo "usage: $0 <Options> <DATADIR> <NETWORK-PORT> <HTTP-PORT>"
echo
echo "Options:"
echo " -s: pass --subscribe-all-subnets to 'lighthouse bn ...', default is not passed"
echo " -d: DEBUG_LEVEL, default info"
echo " -h: this help"
echo
echo "Positional arguments:"
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"
exit
;;
esac
done
# Get positional arguments
data_dir=${@:$OPTIND+0:1}
network_port=${@:$OPTIND+1:1}
http_port=${@:$OPTIND+2:1}
exec lighthouse \
--debug-level $DEBUG_LEVEL \
bn \
--datadir $1 \
$SUBSCRIBE_ALL_SUBNETS \
--datadir $data_dir \
--testnet-dir $TESTNET_DIR \
--staking \
--enr-address 127.0.0.1 \
--enr-udp-port $2 \
--enr-tcp-port $2 \
--port $2 \
--http-port $3 \
--enr-udp-port $network_port \
--enr-tcp-port $network_port \
--port $network_port \
--http-port $http_port \
--disable-packet-filter \
--target-peers $((NODE_COUNT - 1))
--target-peers $((BN_COUNT - 1))

View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
# Kill processes
# First parameter is the file with
# one pid per line.
if [ -f "$1" ]; then
while read pid
do
echo killing $pid
kill $pid
done < $1
fi

View File

@ -6,7 +6,7 @@
# is now + $GENESIS_DELAY.
#
# Generates datadirs for multiple validator keys according to the
# $VALIDATOR_COUNT and $NODE_COUNT variables.
# $VALIDATOR_COUNT and $BN_COUNT variables.
#
set -o nounset -o errexit -o pipefail
@ -45,7 +45,7 @@ lcli \
insecure-validators \
--count $VALIDATOR_COUNT \
--base-dir $DATADIR \
--node-count $NODE_COUNT
--node-count $BN_COUNT
echo Validators generated with keystore passwords at $DATADIR.
echo "Building genesis state... (this might take a while)"

View File

@ -0,0 +1,117 @@
#!/usr/bin/env bash
# Start all processes necessary to create a local testnet
source ./vars.env
# VC_COUNT is defaulted in vars.env
DEBUG_LEVEL=${DEBUG_LEVEL:-info}
# Get options
while getopts "v:d:h" flag; do
case "${flag}" in
v) VC_COUNT=${OPTARG};;
d) DEBUG_LEVEL=${OPTARG};;
h)
validators=$(( $VALIDATOR_COUNT / $BN_COUNT ))
echo "Start local testnet, defaults: 1 eth1 node, $BN_COUNT beacon nodes,"
echo "and $VC_COUNT validator clients with each vc having $validators validators."
echo
echo "usage: $0 <Options>"
echo
echo "Options:"
echo " -v: VC_COUNT default: $VC_COUNT"
echo " -d: DEBUG_LEVEL default: info"
echo " -h: this help"
exit
;;
esac
done
if (( $VC_COUNT > $BN_COUNT )); then
echo "Error $VC_COUNT is too large, must be <= BN_COUNT=$BN_COUNT"
exit
fi
# Init some constants
PID_FILE=$TESTNET_DIR/PIDS.pid
LOG_DIR=$TESTNET_DIR
# Stop local testnet and remove $PID_FILE
./stop_local_testnet.sh
# Clean $DATADIR and create empty log files so the
# user can "tail -f" right after starting this script
# even before its done.
./clean.sh
mkdir -p $LOG_DIR
for (( bn=1; bn<=$BN_COUNT; bn++ )); do
touch $LOG_DIR/beacon_node_$bn.log
done
for (( vc=1; vc<=$VC_COUNT; vc++ )); do
touch $LOG_DIR/validator_node_$vc.log
done
# Sleep with a message
sleeping() {
echo sleeping $1
sleep $1
}
# Execute the command with logs saved to a file.
#
# First parameter is log file name
# Second parameter is executable name
# Remaining parameters are passed to executable
execute_command() {
LOG_NAME=$1
EX_NAME=$2
shift
shift
CMD="$EX_NAME $@ &>> $LOG_DIR/$LOG_NAME"
echo "executing: $CMD"
echo "$CMD" > "$LOG_DIR/$LOG_NAME"
eval "$CMD &"
}
# Execute the command with logs saved to a file
# and is PID is saved to $PID_FILE.
#
# First parameter is log file name
# Second parameter is executable name
# Remaining parameters are passed to executable
execute_command_add_PID() {
execute_command $@
echo "$!" >> $PID_FILE
}
# Start ganache-cli, setup things up and start the bootnode.
# The delays are necessary, hopefully there is a better way :(
# Delay to let ganache-cli to get started
execute_command_add_PID ganache_test_node.log ./ganache_test_node.sh
sleeping 2
# Delay to get data setup
execute_command setup.log ./setup.sh
sleeping 15
# Delay to let boot_enr.yaml to be created
execute_command_add_PID bootnode.log ./bootnode.sh
sleeping 1
# Start beacon nodes
BN_udp_tcp_base=9000
BN_http_port_base=8000
(( $VC_COUNT < $BN_COUNT )) && SAS=-s || SAS=
for (( bn=1; bn<=$BN_COUNT; bn++ )); do
execute_command_add_PID beacon_node_$bn.log ./beacon_node.sh $SAS -d $DEBUG_LEVEL $DATADIR/node_$bn $((BN_udp_tcp_base + $bn)) $((BN_http_port_base + $bn))
done
# Start requested number of validator clients
for (( vc=1; vc<=$VC_COUNT; vc++ )); do
execute_command_add_PID validator_node_$vc.log ./validator_client.sh $DATADIR/node_$vc http://localhost:$((BN_http_port_base + $vc)) $DEBUG_LEVEL
done
echo "Started!"

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# Stop all processes that were started with start_local_testnet.sh
source ./vars.env
PID_FILE=$TESTNET_DIR/PIDS.pid
./kill_processes.sh $PID_FILE
rm -f $PID_FILE

View File

@ -15,10 +15,16 @@ GENESIS_FORK_VERSION=0x42424242
VALIDATOR_COUNT=80
GENESIS_VALIDATOR_COUNT=80
# Number of validator client instances that you intend to run
NODE_COUNT=4
# Number of beacon_node instances that you intend to run
BN_COUNT=4
GENESIS_DELAY=180
# Number of valicator clients
VC_COUNT=$BN_COUNT
# Number of seconds to delay to start genesis block.
# If started by a script this can be 0, if starting by hand
# use something like 180.
GENESIS_DELAY=0
# Port for P2P communication with bootnode
BOOTNODE_PORT=4242

View File

@ -15,9 +15,15 @@ GENESIS_FORK_VERSION=0x42424242
VALIDATOR_COUNT=80
GENESIS_VALIDATOR_COUNT=80
# Number of validator client instances that you intend to run
NODE_COUNT=4
# Number of beacon_node instances that you intend to run
BN_COUNT=4
# Number of valicator clients
VC_COUNT=$BN_COUNT
# Number of seconds to delay to start genesis block.
# If started by a script this can be 0, if starting by hand
# use something like 180.
GENESIS_DELAY=0
# Port for P2P communication with bootnode
@ -29,14 +35,14 @@ NETWORK_ID=4242
# Hard fork configuration
ALTAIR_FORK_EPOCH=18446744073709551615
# Spec version (mainnet or minimal)
SPEC_PRESET=mainnet
# Seconds per Eth2 slot
SECONDS_PER_SLOT=3
# Seconds per Eth1 block
SECONDS_PER_ETH1_BLOCK=1
# Spec preset
SPEC_PRESET=mainnet
# Enable doppelganger detection
VC_ARGS=" --enable-doppelganger-protection "