mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-02 16:21:42 +00:00
Replace local testnet script with Kurtosis (#5865)
* Kurtosis local testnet.
* Remove unused `lcli` subcommands
* Migrate doppelganger_protection test to kurtosis and further cleanup.
* Fix lint
* Add missing download image step and remove unused `lcli` dependencies.
* doppelganger success case working
* Run tests on hosted runner and improve error handling.
* Start the dp vc only after epoch 1
* Add more logging to test results.
* Fix exit code and speed up docker build.
* Fix incorrect exit codes and split doppelganger tests on CI.
* Missing the escape for double quotes 😫
* Remove unnecessary vc params in kurtosis config.
This commit is contained in:
@@ -1,101 +1,129 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Requires `lighthouse`, `lcli`, `geth`, `bootnode`, `curl`, `jq`
|
||||
# Requires `docker`, `kurtosis`, `yq`, `curl`, `jq`
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
NETWORK_PARAMS_FILE=$SCRIPT_DIR/network_params.yaml
|
||||
BEHAVIOR=$1
|
||||
ENCLAVE_NAME=local-testnet-$BEHAVIOR
|
||||
|
||||
SECONDS_PER_SLOT=$(yq eval ".network_params.seconds_per_slot" $NETWORK_PARAMS_FILE)
|
||||
KEYS_PER_NODE=$(yq eval ".network_params.num_validator_keys_per_node" $NETWORK_PARAMS_FILE)
|
||||
LH_IMAGE_NAME=$(yq eval ".participants[0].cl_image" $NETWORK_PARAMS_FILE)
|
||||
|
||||
if [[ "$BEHAVIOR" != "success" ]] && [[ "$BEHAVIOR" != "failure" ]]; then
|
||||
echo "Usage: doppelganger_protection.sh [success|failure]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit_if_fails() {
|
||||
echo $@
|
||||
$@
|
||||
EXIT_CODE=$?
|
||||
if [[ $EXIT_CODE -eq 1 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
function exit_and_dump_logs() {
|
||||
local exit_code=$1
|
||||
echo "Shutting down..."
|
||||
$SCRIPT_DIR/../local_testnet/stop_local_testnet.sh $ENCLAVE_NAME
|
||||
echo "Test completed with exit code $exit_code."
|
||||
exit $exit_code
|
||||
}
|
||||
genesis_file=$2
|
||||
|
||||
source ./vars.env
|
||||
function get_service_status() {
|
||||
local service_name=$1
|
||||
kurtosis service inspect $ENCLAVE_NAME $service_name | grep Status | cut -d':' -f2 | xargs
|
||||
}
|
||||
|
||||
exit_if_fails ../local_testnet/clean.sh
|
||||
function run_command_without_exit() {
|
||||
local command=$1
|
||||
set +e
|
||||
eval "$command"
|
||||
local exit_code=$?
|
||||
set -e
|
||||
echo $exit_code
|
||||
}
|
||||
|
||||
# Start local testnet
|
||||
$SCRIPT_DIR/../local_testnet/start_local_testnet.sh -e $ENCLAVE_NAME -b false -c -n $NETWORK_PARAMS_FILE
|
||||
|
||||
echo "Setting up local testnet"
|
||||
# Immediately stop node 4 (as we only need the node 4 validator keys generated for later use)
|
||||
kurtosis service stop $ENCLAVE_NAME cl-4-lighthouse-geth el-4-geth-lighthouse vc-4-geth-lighthouse > /dev/null
|
||||
|
||||
exit_if_fails ../local_testnet/setup.sh
|
||||
# Get the http port to get the config
|
||||
BN1_HTTP_ADDRESS=`kurtosis port print $ENCLAVE_NAME cl-1-lighthouse-geth http`
|
||||
|
||||
# Duplicate this directory so slashing protection doesn't keep us from re-using validator keys
|
||||
exit_if_fails cp -R $HOME/.lighthouse/local-testnet/node_1 $HOME/.lighthouse/local-testnet/node_1_doppelganger
|
||||
# Get the genesis time and genesis delay
|
||||
MIN_GENESIS_TIME=`curl -s $BN1_HTTP_ADDRESS/eth/v1/config/spec | jq '.data.MIN_GENESIS_TIME|tonumber'`
|
||||
GENESIS_DELAY=`curl -s $BN1_HTTP_ADDRESS/eth/v1/config/spec | jq '.data.GENESIS_DELAY|tonumber'`
|
||||
|
||||
echo "Starting bootnode"
|
||||
CURRENT_TIME=`date +%s`
|
||||
# Note: doppelganger protection can only be started post epoch 0
|
||||
echo "Waiting until next epoch before starting the next validator client..."
|
||||
DELAY=$(( $SECONDS_PER_SLOT * 32 + $GENESIS_DELAY + $MIN_GENESIS_TIME - $CURRENT_TIME))
|
||||
sleep $DELAY
|
||||
|
||||
exit_if_fails ../local_testnet/bootnode.sh &> /dev/null &
|
||||
|
||||
exit_if_fails ../local_testnet/el_bootnode.sh &> /dev/null &
|
||||
|
||||
# wait for the bootnode to start
|
||||
sleep 10
|
||||
|
||||
echo "Starting local execution nodes"
|
||||
|
||||
exit_if_fails ../local_testnet/geth.sh $HOME/.lighthouse/local-testnet/geth_datadir1 6000 5000 4000 $genesis_file &> geth.log &
|
||||
exit_if_fails ../local_testnet/geth.sh $HOME/.lighthouse/local-testnet/geth_datadir2 6100 5100 4100 $genesis_file &> /dev/null &
|
||||
exit_if_fails ../local_testnet/geth.sh $HOME/.lighthouse/local-testnet/geth_datadir3 6200 5200 4200 $genesis_file &> /dev/null &
|
||||
|
||||
sleep 20
|
||||
|
||||
exit_if_fails ../local_testnet/beacon_node.sh -d debug $HOME/.lighthouse/local-testnet/node_1 8000 7000 9000 http://localhost:4000 $HOME/.lighthouse/local-testnet/geth_datadir1/geth/jwtsecret &> /dev/null &
|
||||
exit_if_fails ../local_testnet/beacon_node.sh $HOME/.lighthouse/local-testnet/node_2 8100 7100 9100 http://localhost:4100 $HOME/.lighthouse/local-testnet/geth_datadir2/geth/jwtsecret &> /dev/null &
|
||||
exit_if_fails ../local_testnet/beacon_node.sh $HOME/.lighthouse/local-testnet/node_3 8200 7200 9200 http://localhost:4200 $HOME/.lighthouse/local-testnet/geth_datadir3/geth/jwtsecret &> /dev/null &
|
||||
|
||||
echo "Starting local validator clients"
|
||||
|
||||
exit_if_fails ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_1 http://localhost:9000 &> /dev/null &
|
||||
exit_if_fails ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_2 http://localhost:9100 &> /dev/null &
|
||||
exit_if_fails ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_3 http://localhost:9200 &> /dev/null &
|
||||
|
||||
echo "Waiting an epoch before starting the next validator client"
|
||||
sleep $(( $SECONDS_PER_SLOT * 32 ))
|
||||
# Use BN2 for the next validator client
|
||||
bn_2_url=$(kurtosis service inspect $ENCLAVE_NAME cl-2-lighthouse-geth | grep 'enr-address' | cut -d'=' -f2)
|
||||
bn_2_port=4000
|
||||
|
||||
if [[ "$BEHAVIOR" == "failure" ]]; then
|
||||
|
||||
echo "Starting the doppelganger validator client"
|
||||
echo "Starting the doppelganger validator client."
|
||||
|
||||
# Use same keys as keys from VC1 and connect to BN2
|
||||
# This process should not last longer than 2 epochs
|
||||
timeout $(( $SECONDS_PER_SLOT * 32 * 2 )) ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_1_doppelganger http://localhost:9100
|
||||
DOPPELGANGER_EXIT=$?
|
||||
vc_1_range_start=0
|
||||
vc_1_range_end=$(($KEYS_PER_NODE - 1))
|
||||
vc_1_keys_artifact_id="1-lighthouse-geth-$vc_1_range_start-$vc_1_range_end-0"
|
||||
service_name=vc-1-doppelganger
|
||||
|
||||
echo "Shutting down"
|
||||
kurtosis service add \
|
||||
--files /validator_keys:$vc_1_keys_artifact_id,/testnet:el_cl_genesis_data \
|
||||
$ENCLAVE_NAME $service_name $LH_IMAGE_NAME -- lighthouse \
|
||||
vc \
|
||||
--debug-level debug \
|
||||
--testnet-dir=/testnet \
|
||||
--validators-dir=/validator_keys/keys \
|
||||
--secrets-dir=/validator_keys/secrets \
|
||||
--init-slashing-protection \
|
||||
--beacon-nodes=http://$bn_2_url:$bn_2_port \
|
||||
--enable-doppelganger-protection \
|
||||
--suggested-fee-recipient 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990
|
||||
|
||||
# Cleanup
|
||||
killall geth
|
||||
killall lighthouse
|
||||
killall bootnode
|
||||
# Check if doppelganger VC has stopped and exited. Exit code 1 means the check timed out and VC is still running.
|
||||
check_exit_cmd="until [ \$(get_service_status $service_name) != 'RUNNING' ]; do sleep 1; done"
|
||||
doppelganger_exit=$(run_command_without_exit "timeout $(( $SECONDS_PER_SLOT * 32 * 2 )) bash -c \"$check_exit_cmd\"")
|
||||
|
||||
echo "Done"
|
||||
|
||||
# We expect to find a doppelganger, exit with success error code if doppelganger was found
|
||||
# and failure if no doppelganger was found.
|
||||
if [[ $DOPPELGANGER_EXIT -eq 1 ]]; then
|
||||
exit 0
|
||||
if [[ $doppelganger_exit -eq 1 ]]; then
|
||||
echo "Test failed: expected doppelganger but VC is still running. Check the logs for details."
|
||||
exit_and_dump_logs 1
|
||||
else
|
||||
exit 1
|
||||
echo "Test passed: doppelganger found and VC process stopped successfully."
|
||||
exit_and_dump_logs 0
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [[ "$BEHAVIOR" == "success" ]]; then
|
||||
|
||||
echo "Starting the last validator client"
|
||||
echo "Starting the last validator client."
|
||||
|
||||
../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_4 http://localhost:9100 &
|
||||
DOPPELGANGER_FAILURE=0
|
||||
vc_4_range_start=$(($KEYS_PER_NODE * 3))
|
||||
vc_4_range_end=$(($KEYS_PER_NODE * 4 - 1))
|
||||
vc_4_keys_artifact_id="4-lighthouse-geth-$vc_4_range_start-$vc_4_range_end-0"
|
||||
service_name=vc-4
|
||||
|
||||
kurtosis service add \
|
||||
--files /validator_keys:$vc_4_keys_artifact_id,/testnet:el_cl_genesis_data \
|
||||
$ENCLAVE_NAME $service_name $LH_IMAGE_NAME -- lighthouse \
|
||||
vc \
|
||||
--debug-level debug \
|
||||
--testnet-dir=/testnet \
|
||||
--validators-dir=/validator_keys/keys \
|
||||
--secrets-dir=/validator_keys/secrets \
|
||||
--init-slashing-protection \
|
||||
--beacon-nodes=http://$bn_2_url:$bn_2_port \
|
||||
--enable-doppelganger-protection \
|
||||
--suggested-fee-recipient 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990
|
||||
|
||||
doppelganger_failure=0
|
||||
|
||||
# Sleep three epochs, then make sure all validators were active in epoch 2. Use
|
||||
# `is_previous_epoch_target_attester` from epoch 3 for a complete view of epoch 2 inclusion.
|
||||
@@ -104,20 +132,27 @@ if [[ "$BEHAVIOR" == "success" ]]; then
|
||||
echo "Waiting three epochs..."
|
||||
sleep $(( $SECONDS_PER_SLOT * 32 * 3 ))
|
||||
|
||||
PREVIOUS_DIR=$(pwd)
|
||||
cd $HOME/.lighthouse/local-testnet/node_4/validators
|
||||
# Get VC4 validator keys
|
||||
keys_path=$SCRIPT_DIR/$ENCLAVE_NAME/node_4/validators
|
||||
rm -rf $keys_path && mkdir -p $keys_path
|
||||
kurtosis files download $ENCLAVE_NAME $vc_4_keys_artifact_id $keys_path
|
||||
cd $keys_path/keys
|
||||
|
||||
for val in 0x*; do
|
||||
[[ -e $val ]] || continue
|
||||
curl -s localhost:9100/lighthouse/validator_inclusion/3/$val | jq | grep -q '"is_previous_epoch_target_attester": false'
|
||||
IS_ATTESTER=$?
|
||||
if [[ $IS_ATTESTER -eq 0 ]]; then
|
||||
is_attester=$(run_command_without_exit "curl -s $BN1_HTTP_ADDRESS/lighthouse/validator_inclusion/3/$val | jq | grep -q '\"is_previous_epoch_target_attester\": false'")
|
||||
if [[ $is_attester -eq 0 ]]; then
|
||||
echo "$val did not attest in epoch 2."
|
||||
else
|
||||
echo "ERROR! $val did attest in epoch 2."
|
||||
DOPPELGANGER_FAILURE=1
|
||||
doppelganger_failure=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $doppelganger_failure -eq 1 ]]; then
|
||||
exit_and_dump_logs 1
|
||||
fi
|
||||
|
||||
# Sleep two epochs, then make sure all validators were active in epoch 4. Use
|
||||
# `is_previous_epoch_target_attester` from epoch 5 for a complete view of epoch 4 inclusion.
|
||||
#
|
||||
@@ -126,30 +161,18 @@ if [[ "$BEHAVIOR" == "success" ]]; then
|
||||
sleep $(( $SECONDS_PER_SLOT * 32 * 2 ))
|
||||
for val in 0x*; do
|
||||
[[ -e $val ]] || continue
|
||||
curl -s localhost:9100/lighthouse/validator_inclusion/5/$val | jq | grep -q '"is_previous_epoch_target_attester": true'
|
||||
IS_ATTESTER=$?
|
||||
if [[ $IS_ATTESTER -eq 0 ]]; then
|
||||
is_attester=$(run_command_without_exit "curl -s $BN1_HTTP_ADDRESS/lighthouse/validator_inclusion/5/$val | jq | grep -q '\"is_previous_epoch_target_attester\": true'")
|
||||
if [[ $is_attester -eq 0 ]]; then
|
||||
echo "$val attested in epoch 4."
|
||||
else
|
||||
echo "ERROR! $val did not attest in epoch 4."
|
||||
DOPPELGANGER_FAILURE=1
|
||||
doppelganger_failure=1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Shutting down"
|
||||
|
||||
# Cleanup
|
||||
cd $PREVIOUS_DIR
|
||||
|
||||
killall geth
|
||||
killall lighthouse
|
||||
killall bootnode
|
||||
|
||||
echo "Done"
|
||||
|
||||
if [[ $DOPPELGANGER_FAILURE -eq 1 ]]; then
|
||||
exit 1
|
||||
if [[ $doppelganger_failure -eq 1 ]]; then
|
||||
exit_and_dump_logs 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
exit_and_dump_logs 0
|
||||
|
||||
File diff suppressed because one or more lines are too long
16
scripts/tests/network_params.yaml
Normal file
16
scripts/tests/network_params.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# Full configuration reference [here](https://github.com/kurtosis-tech/ethereum-package?tab=readme-ov-file#configuration).
|
||||
participants:
|
||||
- el_type: geth
|
||||
el_image: ethereum/client-go:latest
|
||||
cl_type: lighthouse
|
||||
cl_image: lighthouse:local
|
||||
cl_extra_params:
|
||||
- --target-peers=3
|
||||
count: 4
|
||||
network_params:
|
||||
deneb_fork_epoch: 0
|
||||
seconds_per_slot: 3
|
||||
num_validator_keys_per_node: 20
|
||||
global_log_level: debug
|
||||
snooper_enabled: false
|
||||
additional_services: []
|
||||
@@ -1,66 +0,0 @@
|
||||
# Path to the geth binary
|
||||
GETH_BINARY=geth
|
||||
EL_BOOTNODE_BINARY=bootnode
|
||||
|
||||
# Base directories for the validator keys and secrets
|
||||
DATADIR=~/.lighthouse/local-testnet
|
||||
|
||||
# Directory for the eth2 config
|
||||
TESTNET_DIR=$DATADIR/testnet
|
||||
|
||||
EL_BOOTNODE_ENODE="enode://51ea9bb34d31efc3491a842ed13b8cab70e753af108526b57916d716978b380ed713f4336a80cdb85ec2a115d5a8c0ae9f3247bed3c84d3cb025c6bab311062c@127.0.0.1:0?discport=30301"
|
||||
|
||||
# Hardcoded deposit contract
|
||||
DEPOSIT_CONTRACT_ADDRESS=4242424242424242424242424242424242424242
|
||||
|
||||
GENESIS_FORK_VERSION=0x42424242
|
||||
|
||||
# Block hash generated from genesis.json in directory
|
||||
ETH1_BLOCK_HASH=7a5c656343c3a66dcf75415958b500e8873f9dab0cd588e6cf0785b52a06dd34
|
||||
|
||||
VALIDATOR_COUNT=80
|
||||
GENESIS_VALIDATOR_COUNT=80
|
||||
|
||||
# Number of beacon_node instances that you intend to run
|
||||
BN_COUNT=4
|
||||
|
||||
# Number of validator 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
|
||||
|
||||
# Network ID and Chain ID of local eth1 test network
|
||||
CHAIN_ID=4242
|
||||
|
||||
# Hard fork configuration
|
||||
ALTAIR_FORK_EPOCH=0
|
||||
BELLATRIX_FORK_EPOCH=0
|
||||
CAPELLA_FORK_EPOCH=0
|
||||
DENEB_FORK_EPOCH=0
|
||||
ELECTRA_FORK_EPOCH=18446744073709551615
|
||||
|
||||
TTD=0
|
||||
|
||||
# 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
|
||||
|
||||
# Proposer score boost percentage
|
||||
PROPOSER_SCORE_BOOST=70
|
||||
|
||||
# Command line arguments for beacon node client
|
||||
BN_ARGS=""
|
||||
|
||||
# Enable doppelganger detection
|
||||
VC_ARGS=" --enable-doppelganger-protection "
|
||||
Reference in New Issue
Block a user