├── helper ├── info.md ├── geth_version.sh ├── restart_docker.sh ├── stop_docker.sh ├── geth_attach.sh ├── update_docker.sh ├── update_other.sh ├── prysm_read_accounts.sh ├── log_viewer.sh ├── create_beacon_service.sh ├── tmux_logviewer.sh ├── gopls_prune.sh ├── compare_blocks.sh ├── emergency_exit.sh ├── prysm_delete_validator.sh ├── grace.sh ├── raw_Commands_WIP.md ├── prysm_fix.sh ├── exit_validator.sh ├── lh_batch_exit.sh ├── prysm_fix_host_ip.sh ├── LogoVector.svg ├── status_batch.sh ├── update_files.sh ├── check_sync.sh ├── bls_to_execution.sh ├── show_version.sh ├── key_mgmt.sh ├── backup_restore.sh └── menu.sh ├── reset ├── readme.md ├── reset_monitoring.sh └── reset_node.sh ├── setup_offline_keygen.sh ├── setup_monitoring.sh ├── setup_validator.sh ├── README.md └── setup_pulse_node.sh /helper/info.md: -------------------------------------------------------------------------------- 1 | # Place for helper Scripts 2 | -------------------------------------------------------------------------------- /helper/geth_version.sh: -------------------------------------------------------------------------------- 1 | # prints out current geth veresion 2 | #!/bin/bash 3 | 4 | docker exec -it execution geth version 5 | -------------------------------------------------------------------------------- /helper/restart_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo docker stop -t 300 execution 4 | sudo docker stop -t 180 beacon 5 | sudo docker stop -t 180 validator 6 | 7 | sudo docker container prune -f 8 | -------------------------------------------------------------------------------- /helper/stop_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo docker stop -t 300 execution 4 | sudo docker stop -t 180 beacon 5 | sudo docker stop -t 180 validator 6 | 7 | sudo docker container prune -f 8 | -------------------------------------------------------------------------------- /helper/geth_attach.sh: -------------------------------------------------------------------------------- 1 | # attaches to geth docker session - change folder accordingly to your setup. 2 | #!/bin/bash 3 | 4 | docker exec -it execution geth attach /blockchain/execution/geth/geth.ipc 5 | -------------------------------------------------------------------------------- /reset/readme.md: -------------------------------------------------------------------------------- 1 | #### RESET_NODE - THIS WILL NUKE YOUR WHOLE /BLOCKCHAIN FOLDER ! 2 | small scripts to reset/delete almost everything that has been created with the setup-routines. Expect the ufw rules, software installation etc... 3 | 4 | run it if you want and know what you are doing ^^ 5 | -------------------------------------------------------------------------------- /helper/update_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Stopping Docker-images..." 4 | docker stop -t 300 execution 5 | docker stop -t 180 beacon 6 | docker stop -t 180 validator 7 | docker container prune -f && docker image prune -f 8 | echo "Removing Docker-images..." 9 | docker rmi registry.gitlab.com/pulsechaincom/go-pulse 10 | docker rmi registry.gitlab.com/pulsechaincom/erigon-pulse 11 | docker rmi registry.gitlab.com/pulsechaincom/lighthouse-pulse 12 | docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain 13 | docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/validator 14 | #docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /helper/update_other.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker stop -t 300 execution 4 | docker stop -t 300 geth 5 | docker stop -t 180 beacon 6 | docker stop -t 180 validator 7 | 8 | # Pull the latest watchtower image 9 | echo "Pulling the latest watchtower image..." 10 | docker pull containrrr/watchtower 11 | 12 | # Launch watchtower container with the --run-once flag 13 | echo "Launching watchtower with the --run-once flag..." 14 | docker run \ 15 | -d \ 16 | --rm \ 17 | -v /var/run/docker.sock:/var/run/docker.sock \ 18 | containrrr/watchtower \ 19 | --run-once \ 20 | --include-stopped \ 21 | --include-restarting \ 22 | --revive-stopped \ 23 | geth \ 24 | execution \ 25 | beacon \ 26 | validator 27 | 28 | echo "Watchtower run-once process has completed." 29 | -------------------------------------------------------------------------------- /helper/prysm_read_accounts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | start_dir=$(pwd) 4 | script_dir=$(dirname "$0") 5 | 6 | source "$script_dir/functions.sh" 7 | check_and_set_network_variables 8 | 9 | # Prompt the user to enter the installation path 10 | read -e -p "Enter the installation path (default: /blockchain): " INSTALL_PATH 11 | 12 | # Set the default installation path if the user didn't enter a value 13 | if [ -z "$INSTALL_PATH" ]; then 14 | INSTALL_PATH="/blockchain" 15 | fi 16 | 17 | # Run the Docker command with the specified installation path 18 | docker run --rm -it \ 19 | --name="read_keys" \ 20 | -v "${INSTALL_PATH}/wallet:/wallet" \ 21 | registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest \ 22 | accounts list \ 23 | --${PRYSM_NETWORK_FLAG} \ 24 | --wallet-dir=/wallet --wallet-password-file=/wallet/pw.txt 25 | 26 | read -p "Press Enter to continue..." 27 | -------------------------------------------------------------------------------- /helper/log_viewer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Close any existing terminal windows with the specified titles 4 | wmctrl -l | grep -w "Execution Logs\|Beacon Logs\|Validator Logs\|HTOP\|DiskUsage" | awk '{print $1}' | xargs -r wmctrl -ic >/dev/null 2>&1 5 | 6 | # Wait for a moment to ensure the previous terminal windows are closed 7 | sleep 2 8 | 9 | # Open new terminal windows and execute the specified commands in each 10 | 11 | gnome-terminal --tab --title="Execution Logs" -- bash -c "docker logs -f --tail=20 execution; exec bash" 12 | 13 | gnome-terminal --tab --title="Beacon Logs" -- bash -c "docker logs -f --tail=20 beacon; exec bash" 14 | 15 | gnome-terminal --tab --title="Validator Logs" -- bash -c "docker logs -f --tail=20 validator; exec bash" 16 | 17 | gnome-terminal --tab --title="HTOP" -- bash -c "htop; exec bash" 18 | 19 | gnome-terminal --tab --title="DiskUsage" -- bash -c "watch df -H; exec bash" 20 | 21 | gnome-terminal --tab --title="Docker Status" -- bash -c "watch docker ps; exec bash" 22 | -------------------------------------------------------------------------------- /helper/create_beacon_service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Prompt the user for the installation path with a default value 4 | read -p "Enter the installation path [/blockchain]: " install_path 5 | install_path=${install_path:-/blockchain} 6 | 7 | # Define the path to the service file 8 | service_file="/etc/systemd/system/beacon.service" 9 | 10 | # Use sudo to create or overwrite the service file 11 | sudo bash -c "cat > $service_file" < /dev/null 2>&1 11 | echo "We will have to stop the validator coontainer first..." 12 | sleep 1 13 | sudo docker stop validator && sudo docker container prune -f > /dev/null 2>&1 14 | echo "Done. proceeding to Account-Deletion.." 15 | echo "" 16 | read -e -p "Please enter your installation folder (default: /blockchain): " INSTALL_PATH 17 | 18 | # Set the default installation path if the user didn't enter a value 19 | if [ -z "$ISNTALL_PATH" ]; then 20 | INSTALL_PATH="/blockchain" 21 | fi 22 | 23 | if [ -f "${INSTALL_PATH}/wallet/direct/accounts/all-accounts.keystore.json" ]; then 24 | sudo chmod -R 0600 "${INSTALL_PATH}/wallet/direct/accounts/all-accounts.keystore.json" 25 | fi 26 | 27 | sudo -u prysm docker run -it \ 28 | --name="delete_valdator" \ 29 | -v "${INSTALL_PATH}/wallet":/wallet \ 30 | registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest \ 31 | accounts delete --"${PRYSM_NETWORK_FLAG}" \ 32 | --wallet-dir=/wallet --wallet-password-file=/wallet/pw.txt 33 | 34 | echo "Now restarting the Validator Container..." 35 | ${INSTALL_PATH}/start_validator.sh > /dev/null 2>&1 36 | sudo docker stop delete_validator > /dev/null 2>&1 37 | sudo docker container prune -f > /dev/null 2>&1 38 | echo "Done..." 39 | echo "" 40 | read -p "Press enter to continue..." 41 | -------------------------------------------------------------------------------- /helper/grace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Prompt the user for the install location with a default value 4 | read -e -p "Please enter the path to your install location (default is /blockchain): " INSTALL_PATH 5 | INSTALL_PATH=${INSTALL_PATH:-/blockchain} # Use default path if user input is empty 6 | INSTALL_PATH=${INSTALL_PATH%/} # Remove trailing slash if exists 7 | 8 | # Define script paths 9 | SCRIPTS=("$INSTALL_PATH/start_consensus.sh" "$INSTALL_PATH/start_execution.sh" "$INSTALL_PATH/start_validator.sh") 10 | 11 | # Iterate over scripts and add them to crontab if they exist and are executable 12 | for script in "${SCRIPTS[@]}" 13 | do 14 | if [[ -x "$script" ]] 15 | then 16 | # Check if the script is already in the cron list 17 | if ! sudo crontab -l 2>/dev/null | grep -q "$script"; then 18 | # If it is not in the list, add script to root's crontab 19 | (sudo crontab -l 2>/dev/null; echo "@reboot $script > /dev/null 2>&1") | sudo crontab - 20 | echo "Added $script to root's cron jobs." 21 | else 22 | echo "Skipping $script - already in root's cron jobs." 23 | fi 24 | else 25 | echo "Skipping $script - does not exist or is not executable." 26 | fi 27 | done 28 | 29 | # Create a systemd service unit file 30 | cat << EOF | sudo tee /etc/systemd/system/graceful_stop.service 31 | [Unit] 32 | Description=Gracefully stop docker containers on shutdown 33 | 34 | [Service] 35 | ExecStart=/bin/true 36 | ExecStop=$INSTALL_PATH/helper/stop_docker.sh 37 | RemainAfterExit=yes 38 | 39 | [Install] 40 | WantedBy=multi-user.target 41 | EOF 42 | 43 | # Reload systemd manager configuration 44 | sudo systemctl daemon-reload 45 | 46 | # Enable the new service to be started on bootup 47 | sudo systemctl enable graceful_stop.service 48 | sudo systemctl start graceful_stop.service 49 | 50 | echo "Set up and enabled graceful_stop service. Activated cronjob to always restart docker clients after a reboot" 51 | read -p "Press Enter to continue" 52 | 53 | -------------------------------------------------------------------------------- /reset/reset_monitoring.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TABLE="\ 4 | +-------------------------------------------------------------+ 5 | | This script will remove all Prometheus/Grafana related | 6 | | changes. | 7 | | | 8 | | Do you want to continue (y/n)? | 9 | +-------------------------------------------------------------+ 10 | | If yes, the following actions will be taken: | 11 | | | 12 | | 1. Stop Docker containers | 13 | | 2. Remove Containers | 14 | | 3. Remove stopped containers | 15 | | 4. Remove Prometheus and Grafana users | 16 | | 5. Remove Prometheus and Grafana data directories | 17 | | 6. Remove Prometheus configuration file | 18 | | | 19 | | Are you sure you want to continue (y/n)? | 20 | +-------------------------------------------------------------+ 21 | 22 | " 23 | clear 24 | echo "$TABLE" 25 | read -p "Enter 'y' to continue or 'n' to cancel: " answer 26 | 27 | if [[ $answer == "y" ]] || [[ $answer == "Y" ]]; then 28 | echo "Resetting and removing files..." 29 | 30 | # Stop Docker containers 31 | sudo docker stop grafana prometheus node_exporter 32 | 33 | # Remove Containers 34 | sudo docker rm grafana prometheus node_exporter 35 | 36 | # Remove stopped containers 37 | sudo docker container prune -f 38 | sudo docker rmi grafana/grafana 39 | sudo docker rmi prom/prometheus 40 | sudo docker rmi curlimages/curl 41 | sudo docker rmi prom/node-exporter 42 | 43 | # Remove Prometheus and Grafana users 44 | sudo userdel prometheus 45 | sudo userdel grafana 46 | 47 | # Remove Prometheus and Grafana data directories 48 | sudo rm -R /blockchain/prometheus 49 | sudo rm -R /blockchain/grafana 50 | 51 | # Remove Prometheus configuration file 52 | sudo rm /blockchain/prometheus.yml 53 | sudo rm /blockchain/start_monitoring.sh 54 | else 55 | echo "Exiting the script." 56 | exit 0 57 | fi 58 | -------------------------------------------------------------------------------- /helper/raw_Commands_WIP.md: -------------------------------------------------------------------------------- 1 | ### Prunning DB with geth 2 | ###### note: ajdust the /blockchain part of the command to your setup... 3 | 4 | ```bash 5 | sudo docker stop -t 300 execution && sudo docker container prune -f \ 6 | 7 | sudo docker run --rm --name geth_prune -it -v /home/blockchain/execution/geth:/geth \ 8 | registry.gitlab.com/pulsechaincom/go-pulse:latest \ 9 | snapshot prune-state \ 10 | --datadir /geth 11 | 12 | #sudo -u geth docker run --rm -it --name="geth_prun" \ 13 | #-v /blockchain/execution/geth/:/blockchain \ 14 | #registry.gitlab.com/pulsechaincom/go-pulse:latest \ 15 | #snapshot prune-state \ 16 | #--datadir /blockchain/geth 17 | 18 | ``` 19 | ### Show Version 20 | 21 | ###### Prysm beacon 22 | ```bash 23 | docker exec -it beacon /app/cmd/beacon-chain/beacon-chain --version 24 | ``` 25 | 26 | ###### Prysm validator 27 | ```bash 28 | docker exec -it validator /app/cmd/validator/validator --version 29 | ``` 30 | 31 | ###### Lighthouse beacon & validator 32 | ```bash 33 | curl -X GET "http://localhost:5052/eth/v1/node/version" -H 'accept: application/json' | jq 34 | ``` 35 | 36 | ###### Geth 37 | 38 | ```bash 39 | docker exec -it execution geth version 40 | ``` 41 | 42 | ### List keys currently validating with prysm 43 | ###### note: ajdust the blockchain part of the command to your setup... 44 | ```bash 45 | docker run --rm -it -v "/blockchain/wallet:/wallet" registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest accounts list --pulsechain-testnet-v4 --wallet-dir=/wallet --wallet-password-file=/wallet/pw.txt 46 | ``` 47 | 48 | ### Get Validator infos from local beacon 49 | ###### note: replace YOUR_VALIDATOR_INDEX with the index from beacon-explorer...e.g. 7654 50 | 51 | prym: 52 | ```bash 53 | curl -X 'GET' 'http://127.0.0.1:3500/eth/v1/beacon/states/head/validators/YOUR_VALIDATOR_INDEX' -H 'accept: application/json' 54 | ``` 55 | 56 | lighthouse: 57 | ```bash 58 | curl -X 'GET' 'http://127.0.0.1:5052/eth/v1/beacon/states/head/validators/YOUR_VALIDATOR_INDEX' -H 'accept: application/json' 59 | ``` 60 | 61 | ### Submit bls-to-execution change to beacon 62 | ###### note: @filename is the json generated from the bls-to-exeuction converion via staking-cli 63 | 64 | prysm: 65 | ```bash 66 | curl -X 'POST' \ 67 | 'localhost:3500/eth/v1/beacon/pool/bls_to_execution_changes' \ 68 | -H 'accept: */*' \ 69 | -H 'Content-Type: application/json' \ 70 | -d @filename.json 71 | ``` 72 | 73 | lighthouse: 74 | ```bash 75 | curl -X 'POST' \ 76 | 'localhost:5052/eth/v1/beacon/pool/bls_to_execution_changes' \ 77 | -H 'accept: */*' \ 78 | -H 'Content-Type: application/json' \ 79 | -d @filename.json 80 | ``` 81 | -------------------------------------------------------------------------------- /reset/reset_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define the ASCII table as a multi-line string 4 | TABLE=" 5 | +-------------------------------------------------------------+ 6 | | This script will reset and remove everything Node/Validator | 7 | | related! It defaults to /blockchain folder, and deletes | 8 | | everything that has been put in there, including the | 9 | | downloaded Docker images. | 10 | +-------------------------------------------------------------+ 11 | | WARNING: The files deleted are gone and cannot be recovered!| 12 | +-------------------------------------------------------------+ 13 | | Action Summary | 14 | +-------------------------------------------------------------+ 15 | | 1. Stop Docker containers | 16 | | 2. Remove containers | 17 | | 3. Remove stopped containers | 18 | | 4. Remove Node and Validator users | 19 | | 5. Remove Node and Validator data directories ! | 20 | | 6. Remove configuration files | 21 | +-------------------------------------------------------------+ 22 | | Are you sure you want to continue? (y/n) | 23 | +-------------------------------------------------------------+" 24 | 25 | clear 26 | # Print the ASCII table to the terminal 27 | echo "$TABLE" 28 | 29 | # Prompt the user for confirmation 30 | read -p "Enter 'y' to continue or 'n' to cancel: " answer 31 | 32 | # If the user confirms, proceed with the script 33 | if [ "$answer" == "y" ]; then 34 | # Perform the reset and removal actions here 35 | echo "Resetting and removing files..." 36 | 37 | sudo docker stop execution 38 | sudo docker stop beacon 39 | sudo docker stop validator 40 | 41 | sudo docker rm execution 42 | sudo docker rm beacon 43 | sudo docker rm validator 44 | 45 | sudo docker container prune -f 46 | 47 | sudo docker rmi registry.gitlab.com/pulsechaincom/go-pulse:latest 48 | sudo docker rmi registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest 49 | sudo docker rmi registry.gitlab.com/pulsechaincom/erigon-pulse:latest 50 | sudo docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse:latest 51 | sudo docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl 52 | sudo docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/validator 53 | sudo docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain 54 | sudo docker rmi registry.gitlab.com/pulsechaincom/go-pulse 55 | 56 | sudo userdel validator 57 | sudo userdel geth 58 | sudo userdel lighthouse 59 | sudo userdel prysm 60 | sudo userdel erigon 61 | 62 | sudo rm -R /blockchain 63 | 64 | else 65 | echo "Aborting reset and removal..." 66 | exit 1 67 | fi 68 | -------------------------------------------------------------------------------- /helper/prysm_fix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | clear 4 | 5 | echo "" 6 | echo "This solution addresses issues faced by users with the v2.2.3 update of Prysm." 7 | echo "It switches the docker images from using the latest tag to the stable v2.2.2 version." 8 | echo "" 9 | echo "Once a subsequent update resolves the problem, you can revert to using the latest tag." 10 | echo "" 11 | 12 | 13 | # Prompt the user for the installation directory 14 | read -p "Enter install directory [default: /blockchain]: " install_dir 15 | 16 | # Set default if user input is empty 17 | install_dir=${install_dir:-/blockchain} 18 | 19 | # List of specified files 20 | files=( 21 | "$install_dir/helper/bls_to_execution.sh" 22 | "$install_dir/helper/prysm_delete_validator.sh" 23 | "$install_dir/helper/raw_Commands_WIP.md" 24 | "$install_dir/helper/setup_validator.sh" 25 | "$install_dir/helper/prysm_read_accounts.sh" 26 | "$install_dir/helper/key_mgmt.sh" 27 | "$install_dir/helper/functions.sh" 28 | "$install_dir/start_validator.sh" 29 | "$install_dir/start_consensus.sh" 30 | ) 31 | 32 | # Replace function 33 | replace_in_files() { 34 | for file in "${files[@]}"; do 35 | if [[ -f "$file" ]] && grep -q "$1" "$file"; then 36 | sed -i "s|$1|$2|g" "$file" 37 | echo "Replaced in $file" 38 | fi 39 | done 40 | } 41 | 42 | # Display menu 43 | echo "Choose an option:" 44 | echo "1) Apply fix to use :v2.2.2" 45 | echo "2) Revert back to :latest" 46 | echo "" 47 | 48 | # Take user input 49 | read -p "Your choice [1/2]: " choice 50 | 51 | case $choice in 52 | 1) 53 | replace_in_files "registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:latest" "registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:v2.2.2" 54 | replace_in_files "registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest" "registry.gitlab.com/pulsechaincom/prysm-pulse/validator:v2.2.2" 55 | replace_in_files "registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain:latest" "registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain:v2.2.2" 56 | ;; 57 | 58 | 2) 59 | replace_in_files "registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:v2.2.2" "registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:latest" 60 | replace_in_files "registry.gitlab.com/pulsechaincom/prysm-pulse/validator:v2.2.2" "registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest" 61 | replace_in_files "registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain:v2.2.2" "registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain:latest" 62 | ;; 63 | 64 | *) 65 | echo "Invalid choice. Exiting..." 66 | exit 1 67 | ;; 68 | esac 69 | 70 | echo "Operation completed!" 71 | echo "" 72 | echo "Please restart beacon / validator accordingly" 73 | echo "" 74 | read -p "Press Enter to continue..." 75 | -------------------------------------------------------------------------------- /helper/exit_validator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit Validator 4 | 5 | start_dir=$(pwd) 6 | script_dir=$(dirname "$0") 7 | 8 | source "$script_dir/functions.sh" 9 | 10 | tab_autocomplete 11 | check_and_set_network_variables 12 | 13 | function get_user_choices() { 14 | echo "-----------------------------------------" 15 | echo " Choose your Validator Client " 16 | echo "-----------------------------------------" 17 | echo "(based on your consensus/beacon Client)" 18 | echo "" 19 | echo "Lighthouse Options" 20 | echo "---------------------------------------" 21 | echo "1. Lighthouse - single key exit" 22 | echo "2. Lighthouse - multiple keys exit" 23 | echo "" 24 | echo "Prysm Options" 25 | echo "---------------------------------------" 26 | echo "3. Prysm - single or multiple key exit" 27 | echo "" 28 | echo "Emergency Options" 29 | echo "---------------------------------------" 30 | echo "E. Emergency exit on unsynced node using g4mm4´s external API" 31 | echo "" 32 | echo "General Options" 33 | echo "---------------------------------------" 34 | echo "0. Return or Exit" 35 | echo "" 36 | read -p "Enter your choice (1, 2, 3, E, or 0): " client_choice 37 | 38 | # Validate user input for client choice 39 | while [[ ! "$client_choice" =~ ^[123E0]$ ]]; do 40 | echo "Invalid input. Please enter a valid choice (1, 2, 3, E, or 0): " 41 | read -p "Enter your choice (1, 2, 3, E, or 0): " client_choice 42 | done 43 | 44 | if [[ "$client_choice" == "0" ]]; then 45 | echo "Exiting..." 46 | exit 0 47 | fi 48 | 49 | echo "${client_choice}" 50 | } 51 | 52 | get_user_choices 53 | get_main_user 54 | 55 | if [[ "$client_choice" == "1" ]]; then # lighthouse 56 | get_install_path 57 | while true; do 58 | start_script "../start_validator" > /dev/null 2>&1 59 | exit_validator_LH 60 | stop_docker_container "exit_validator" > /dev/null 2>&1 61 | sudo docker container prune -f > /dev/null 2>&1 62 | press_enter_to_continue 63 | read -p "Would you like to exit another Validator? (y/n): " user_input 64 | if [[ "${user_input,,}" == "n" ]]; then 65 | break 66 | fi 67 | done 68 | exit 0 69 | 70 | elif [[ "$client_choice" == "2" ]]; then # Lighthouse Multi-Key Exit 71 | get_install_path 72 | start_script "lh_batch_exit" 73 | exit 0 74 | 75 | elif [[ "$client_choice" == "3" ]]; then # PRYSM 76 | get_install_path 77 | start_script "../start_validator" > /dev/null 2>&1 78 | exit_validator_PR 79 | stop_docker_container "exit_validator" > /dev/null 2>&1 80 | sudo docker container prune -f > /dev/null 2>&1 81 | sudo docker restart validator 82 | press_enter_to_continue 83 | exit 0 84 | 85 | elif [[ "$client_choice" == "E" ]]; then # Emergency exit 86 | get_install_path 87 | start_script "emergency_exit" 88 | press_enter_to_continue 89 | exit 0 90 | fi 91 | -------------------------------------------------------------------------------- /helper/lh_batch_exit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\n\n" 4 | echo " *********************************************************************************************************" 5 | echo " * *" 6 | echo " * WARNING: This script is designed for batch-processing multiple keystore-files, and will *" 7 | echo " * voluntarily exit the assigned validator for each keystore-file. This action is irreversible. *" 8 | echo " * Please ensure you fully understand the implications of this action before proceeding. *" 9 | echo " * *" 10 | echo " * This is for Lighthouse validators only. It may be a good idea to copy the keystore *" 11 | echo " * files you want to process to a different location and set accordingly in the following steps. *" 12 | echo " * *" 13 | echo " *********************************************************************************************************" 14 | echo -e "\n\n" 15 | 16 | read -p "Do you wish to proceed (y/n)? " answer 17 | case ${answer:0:1} in 18 | y|Y ) 19 | echo "Proceeding..." 20 | ;; 21 | * ) 22 | echo "Aborting..." 23 | exit 24 | ;; 25 | esac 26 | 27 | read -e -p "Enter your installation path (default is /blockchain): " INSTALL_PATH 28 | INSTALL_PATH=${INSTALL_PATH:-/blockchain} 29 | 30 | 31 | echo "Enter your password file path (default is $INSTALL_PATH/keystore_pw.txt)" 32 | read -e -p "If none exists, it will be created, just hit enter: " PASSWORD_FILE 33 | echo "" 34 | PASSWORD_FILE=${PASSWORD_FILE:-$INSTALL_PATH/keystore_pw.txt} 35 | 36 | # Check if password file exists 37 | if [[ ! -f "$PASSWORD_FILE" ]]; then 38 | echo "Password file not found. Creating one..." 39 | read -s -p "Enter your keystore password: " keystore_pw 40 | echo $keystore_pw > $PASSWORD_FILE 41 | chmod 600 $PASSWORD_FILE 42 | echo "Password file created." 43 | fi 44 | 45 | read -p "Enter your keystore files directory (default is $INSTALL_PATH/validator_keys): " KEYSTORE_DIR 46 | KEYSTORE_DIR=${KEYSTORE_DIR:-$INSTALL_PATH/validator_keys} 47 | 48 | BEACON_NODE=http://localhost:5052 49 | 50 | # Ensure the log file is empty before we start 51 | echo "" > $INSTALL_PATH/processed_keystores.log 52 | 53 | for KEYSTORE_FILE in $KEYSTORE_DIR/key*.json 54 | do 55 | echo "Processing $KEYSTORE_FILE..." 56 | sudo -u lighthouse docker exec -it validator lighthouse \ 57 | --network pulsechain \ 58 | account validator exit \ 59 | --keystore=$KEYSTORE_FILE \ 60 | --password-file=$PASSWORD_FILE \ 61 | --beacon-node $BEACON_NODE \ 62 | --datadir $INSTALL_PATH 63 | 64 | echo "$KEYSTORE_FILE processed." | tee -a $INSTALL_PATH/processed_keystores.log 65 | done 66 | 67 | echo "All done! You can find the log file at $INSTALL_PATH/processed_keystores.log" 68 | echo "" 69 | echo "Press Enter to continue" 70 | read -p "" 71 | -------------------------------------------------------------------------------- /helper/prysm_fix_host_ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "This script is only for clients using Prysm. Do not run this if you use Lighthouse." 4 | 5 | # Prompt the user to press Enter to continue or any other key to exit 6 | read -n1 -p "Press Enter to continue or any other key to exit... " key 7 | 8 | # Check the input 9 | if [ "$key" = '' ]; then 10 | echo -e "\nContinuing..." 11 | else 12 | echo -e "\nExiting..." 13 | exit 0 14 | fi 15 | 16 | # Prompt for the /blockchain folder 17 | read -e -p "Enter your blockchain install folder (default is /blockchain): " blockchain_folder 18 | blockchain_folder=${blockchain_folder:-/blockchain} 19 | 20 | # Specify the path to your start script 21 | start_script_path="${blockchain_folder}/start_consensus.sh" 22 | 23 | # Check if the script contains the line for Prysm 24 | if ! grep -q "prysm" "$start_script_path"; then 25 | echo "Prysm line not found in the script. Exiting..." 26 | echo "" 27 | fi 28 | 29 | # Flag to indicate if the IP retrieval block was added 30 | ip_block_added=false 31 | 32 | # Check if the IP retrieval block already exists 33 | if ! grep -q "# Retrieve the current IP address" "$start_script_path"; then 34 | # Backup the original start script 35 | cp "$start_script_path" "${start_script_path}.bak" 36 | 37 | # Prepare the IP retrieval block with an additional empty line at the end 38 | ip_retrieval_block="#!/bin/bash 39 | 40 | # Retrieve the current IP address 41 | IP=\$(curl -s ipinfo.io/ip) 42 | if [ -z \"\$IP\" ]; then 43 | echo \"Failed to retrieve IP address. Exiting...\" 44 | exit 1 45 | fi 46 | 47 | " 48 | # Insert the IP retrieval block 49 | { echo "$ip_retrieval_block"; tail -n +2 "${start_script_path}.bak"; } > "$start_script_path" 50 | ip_block_added=true 51 | fi 52 | 53 | 54 | p2p_line_updated=false 55 | 56 | # Find the line with --p2p-host-ip and replace it, or add it before the last line if it doesn't exist 57 | if grep -q -- "--p2p-host-ip" "$start_script_path"; then 58 | # Replace the existing --p2p-host-ip line 59 | sed -i "/--p2p-host-ip/c\--p2p-host-ip \$IP \\\\" "$start_script_path" 60 | p2p_line_updated=true 61 | else 62 | # Add the --p2p-host-ip line before the last line if it doesn't exist 63 | sed -i "/^$/d; \$i\\--p2p-host-ip \$IP \\\\" "$start_script_path" 64 | p2p_line_updated=true 65 | fi 66 | 67 | # Make sure the start_consensus.sh script is executable 68 | sudo chmod +x "$start_script_path" 69 | 70 | # Output what has been updated 71 | if $ip_block_added; then 72 | echo "IP retrieval block was added to the script." 73 | fi 74 | 75 | if $p2p_line_updated; then 76 | if $ip_block_added; then 77 | echo "Additionally, the --p2p-host-ip line was updated." 78 | else 79 | echo "The --p2p-host-ip line was updated." 80 | fi 81 | else 82 | echo "No changes were made to the --p2p-host-ip line." 83 | fi 84 | 85 | echo "Updated $start_script_path successfully, restarting beacon client now" 86 | echo "" 87 | sleep 1 88 | sudo docker stop -t 180 beacon 89 | echo "" 90 | sudo docker container prune -f 91 | echo "" 92 | sudo ${blockchain_folder}/start_consensus.sh 93 | echo "" 94 | echo "Adding beacon startup as system service" 95 | sudo ${blockchain_folder}/helper/create_beacon_service.sh 96 | echo "" 97 | read -n1 -p "Press Enter to exit... " 98 | -------------------------------------------------------------------------------- /helper/LogoVector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | PulseChain Logo Shape 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /helper/status_batch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define your beacon node address 4 | BEACON_NODE=http://localhost 5 | 6 | # Prompt the user for the install location with a default value 7 | read -e -p "Please enter the path to your install location (default is /blockchain): " INSTALL_PATH 8 | INSTALL_PATH=${INSTALL_PATH:-/blockchain} 9 | 10 | # Let the user know about the default value 11 | echo "The installation path is set to $INSTALL_PATH" 12 | 13 | # Define the path to your file 14 | INDICES_FILE="$INSTALL_PATH/valis.txt" 15 | 16 | # Check if the indices file exists 17 | if [ ! -f "$INDICES_FILE" ]; then 18 | read -p "$INDICES_FILE not found. This file will be used to store the indices of validators you want to check in the future. Would you like to create it now? (y/n): " create_file 19 | if [[ "$create_file" =~ ^[Yy]$ ]] 20 | then 21 | echo "#Add one validator-indices you want to check on per line" > $INDICES_FILE 22 | nano $INDICES_FILE 23 | fi 24 | fi 25 | 26 | # Ask user for hardcoded indices 27 | read -p "Enter any validator indices to check that are not listed in valis.txt, separated by commas: " indices 28 | HARDCODED_INDICES=(${indices//,/ }) 29 | 30 | # Ask user if they want to run the script in a loop 31 | read -p "Do you want to run this script in a loop? (y/n): " run_in_loop 32 | run_in_loop=${run_in_loop:-y} 33 | 34 | # Function to process validators 35 | function process_validators { 36 | # Read from external file if it exists 37 | if [ -f "$INDICES_FILE" ]; then 38 | while read -r VALIDATOR_INDEX 39 | do 40 | echo "Processing validator index $VALIDATOR_INDEX..." 41 | 42 | # Check ports 43 | check_and_run_curl $VALIDATOR_INDEX 44 | 45 | echo "Finished processing validator index $VALIDATOR_INDEX." 46 | 47 | # Sleep for 3 seconds 48 | sleep 3 49 | done < "$INDICES_FILE" 50 | else 51 | echo "File $INDICES_FILE not found!" 52 | fi 53 | 54 | # Process hardcoded indices 55 | for VALIDATOR_INDEX in "${HARDCODED_INDICES[@]}" 56 | do 57 | echo "Processing validator index $VALIDATOR_INDEX..." 58 | 59 | # Check ports 60 | check_and_run_curl $VALIDATOR_INDEX 61 | 62 | echo "Finished processing validator index $VALIDATOR_INDEX." 63 | 64 | # Sleep for 3 seconds 65 | sleep 3 66 | done 67 | } 68 | 69 | # Function to check ports and run curl commands 70 | function check_and_run_curl { 71 | if nc -z localhost 5052; then 72 | # Run the POST curl command for the current validator index 73 | curl -s -S -X POST "$BEACON_NODE:5052/lighthouse/ui/validator_metrics" -d "{\"indices\": [$1]}" -H "Content-Type: application/json" | jq 74 | # Run the GET curl command for the current validator index 75 | curl -s -S -X GET "$BEACON_NODE:5052/eth/v1/beacon/states/head/validators/$1" -H "accept: application/json" | jq 76 | elif nc -z localhost 3500; then 77 | # Run the GET curl command for the current validator index 78 | curl -s -S -X GET "$BEACON_NODE:3500/eth/v1/beacon/states/head/validators/$1" -H "accept: application/json" | jq 79 | else 80 | echo "Neither port 5052 nor port 3500 is reachable!" 81 | fi 82 | } 83 | 84 | # Run once or in a loop 85 | if [[ "$run_in_loop" =~ ^[Yy]$ ]] 86 | then 87 | while true 88 | do 89 | process_validators 90 | echo "Finished one cycle, starting another..." 91 | echo "interrupt with Ctrl.C" 92 | done 93 | else 94 | process_validators 95 | echo "Finished processing validators." 96 | read -p "Press any key to exit" 97 | fi 98 | -------------------------------------------------------------------------------- /helper/update_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to check if a URL is reachable 4 | is_url_reachable() { 5 | if curl --output /dev/null --silent --head --fail "$1"; then 6 | return 0 7 | else 8 | return 1 9 | fi 10 | } 11 | 12 | # Define the primary and fallback GitLab repository URLs 13 | PRIMARY_REPO_URL="https://github.com/tdslaine/install_pulse_node.git" 14 | FALLBACK_REPO_URL="https://gitlab.com/dipslayer/install_pulse_node.git" 15 | 16 | # Define a temporary directory to clone the repository 17 | TMP_DIR=$(mktemp -d -t ci-$(date +%Y-%m-%d-%H-%M-%S)-XXXXXXXXXX) 18 | 19 | # Check if the primary URL is reachable, if not, use the fallback URL 20 | REPO_URL=$PRIMARY_REPO_URL 21 | if ! is_url_reachable "$PRIMARY_REPO_URL"; then 22 | echo "Primary URL is not reachable. Switching to fallback URL." 23 | REPO_URL=$FALLBACK_REPO_URL 24 | fi 25 | 26 | # Clone the repository to the temporary directory 27 | git clone $REPO_URL $TMP_DIR 28 | 29 | # Prompt the user for the install location with a default value 30 | read -e -p "Please enter the path to your install location (default is /blockchain): " INSTALL_PATH 31 | INSTALL_PATH=${INSTALL_PATH:-/blockchain} 32 | 33 | # Verify the directory exists or create it 34 | if [ ! -d "$INSTALL_PATH" ]; then 35 | echo "Directory $INSTALL_PATH does not exist" 36 | exit 1 37 | fi 38 | 39 | # Get the current username and store it in the variable main_user 40 | main_user=$(whoami) 41 | 42 | # Replace the value of CUSTOM_PATH with the actual INSTALL_PATH in menu.sh 43 | sed -i "/^CUSTOM_PATH=/c\CUSTOM_PATH=\"$INSTALL_PATH\"" $TMP_DIR/helper/menu.sh 44 | sed -i "/^helper_scripts_path=/c\helper_scripts_path=\"$INSTALL_PATH/helper\"" $TMP_DIR/helper/menu.sh 45 | 46 | cp $TMP_DIR/setup_validator.sh $INSTALL_PATH/helper 47 | cp $TMP_DIR/setup_monitoring.sh $INSTALL_PATH/helper 48 | cp $TMP_DIR/helper/* $INSTALL_PATH/helper/ 49 | sudo mv $INSTALL_PATH/helper/menu.sh $INSTALL_PATH 50 | 51 | sudo chmod +x $INSTALL_PATH/helper/*.sh 52 | sudo chmod +x $INSTALL_PATH/menu.sh 53 | 54 | sudo chown $main_user $INSTALL_PATH/helper/*.sh 55 | sudo chown $main_user $INSTALL_PATH/menu.sh 56 | 57 | # Create a symbolic link of the menu.sh file in /usr/local/bin and name it plsmenu 58 | sudo rm /usr/local/bin/plsmenu 59 | sudo ln -sf $INSTALL_PATH/menu.sh /usr/local/bin/plsmenu 60 | 61 | # Remove the temporary directory 62 | rm -rf $TMP_DIR 63 | 64 | echo "Update completed successfully." 65 | echo "Press Enter to quit" 66 | read -p "" 67 | 68 | # Adding the cronjobs to restart docker-scripts here 69 | # Define script paths 70 | INSTALL_PATH=${INSTALL_PATH%/} 71 | SCRIPTS=("$INSTALL_PATH/start_consensus.sh" "$INSTALL_PATH/start_execution.sh" "$INSTALL_PATH/start_validator.sh") 72 | 73 | # Iterate over scripts and add them to crontab if they exist and are executable 74 | for script in "${SCRIPTS[@]}" 75 | do 76 | if [[ -x "$script" ]] 77 | then 78 | # Check if the script is already in the cron list 79 | if ! sudo crontab -l 2>/dev/null | grep -q "$script"; then 80 | # If it is not in the list, add script to root's crontab 81 | (sudo crontab -l 2>/dev/null; echo "@reboot $script > /dev/null 2>&1") | sudo crontab - 82 | echo "Added $script to root's cron jobs." 83 | else 84 | echo "$script is already in the cron jobs." 85 | fi 86 | else 87 | echo "Skipping $script - does not exist or is not executable." 88 | fi 89 | done 90 | 91 | echo "Process completed." 92 | exec /usr/local/bin/plsmenu 93 | -------------------------------------------------------------------------------- /helper/check_sync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Functions 4 | epoch_to_time(){ 5 | expr 1683785555 + \( $1 \* 320 \) 6 | } 7 | 8 | time_to_epoch(){ 9 | expr \( $1 - 1683785555 \) / 320 10 | } 11 | 12 | get_committee(){ 13 | URLSTEM="${BEACON_NODE}/eth/v1/beacon/states/finalized" 14 | curl -X GET "${URLSTEM}/sync_committees?epoch=$1" 2> /dev/null \ 15 | | sed -e 's/["]/''/g' | cut -d'[' -f2 | cut -d']' -f1 | tr ',' '\n' 16 | } 17 | 18 | search_committee(){ 19 | FOUND_VALIDATORS=$(get_committee $2 | grep -Ex $VALIDATOR_LIST) 20 | if [ -n "$FOUND_VALIDATORS" ]; then 21 | echo "$FOUND_VALIDATORS" | awk -v c=$1 '{print "validator:", $1, "found in", c, "sync committee"}' 22 | echo "$FOUND_VALIDATORS" | wc -l 23 | else 24 | echo 0 25 | fi 26 | } 27 | 28 | display_epoch(){ 29 | echo "epoch: $1 : $(date -d@$(epoch_to_time $1)) <-- $2" 30 | } 31 | 32 | get_prysm_indices() { 33 | PUBKEYS=$(docker exec validator /app/cmd/validator/validator accounts list --wallet-dir=/wallet --wallet-password-file=/wallet/pw.txt | grep "validating public key" | awk '{print $4}') 34 | echo "" 35 | > validator_indices.txt 36 | for pubkey in $PUBKEYS; do 37 | echo "[DEBUG] Retrieved Public Key: $pubkey" 38 | INDEX=$(curl -s -X GET "http://localhost:3500/eth/v1/beacon/states/head/validators/$pubkey" | jq .data.index) 39 | echo "[DEBUG] Index for Public Key $pubkey: $INDEX" 40 | echo $INDEX >> validator_indices.txt 41 | done 42 | sed -i 's/"//g' validator_indices.txt 43 | } 44 | 45 | get_lighthouse_indices() { 46 | PUBKEYS=$(docker exec beacon lighthouse account validator list -d /blockchain | grep -Eo '0x[a-fA-F0-9]{96}') 47 | > validator_indices.txt 48 | for pubkey in $PUBKEYS; do 49 | echo "[DEBUG] Retrieved Public Key: $pubkey" 50 | INDEX=$(curl -s -X GET "http://localhost:5052/eth/v1/beacon/states/head/validators/$pubkey" | jq .data.index) 51 | echo "[DEBUG] Index for Public Key $pubkey: $INDEX" 52 | echo $INDEX >> validator_indices.txt 53 | done 54 | sed -i 's/"//g' validator_indices.txt 55 | } 56 | 57 | # Main script 58 | echo "Please choose your client:" 59 | echo "1. Lighthouse" 60 | echo "2. Prysm" 61 | read -p "Enter your choice (1/2): " choice 62 | 63 | case $choice in 64 | 1) 65 | BEACON_NODE="http://localhost:5052" 66 | get_lighthouse_indices 67 | ;; 68 | 2) 69 | BEACON_NODE="http://localhost:3500" 70 | get_prysm_indices 71 | ;; 72 | *) 73 | echo "Invalid choice!" 74 | exit 1 75 | ;; 76 | esac 77 | 78 | # Continue with the rest of the script 79 | CURR_EPOCH=$(time_to_epoch $(date +%s)) 80 | CURR_START_EPOCH=`expr \( $CURR_EPOCH / 256 \) \* 256` 81 | NEXT_START_EPOCH=`expr $CURR_START_EPOCH + 256` 82 | NEXTB1_START_EPOCH=`expr $NEXT_START_EPOCH + 256` 83 | 84 | echo 85 | display_epoch $CURR_START_EPOCH "current sync committee start" 86 | display_epoch $CURR_EPOCH "now" 87 | display_epoch $NEXT_START_EPOCH "next sync committee start" 88 | display_epoch $NEXTB1_START_EPOCH "next-but-one sync committee start" 89 | echo 90 | 91 | VALIDATOR_LIST=$(cat validator_indices.txt | tr '\n' '|' | sed 's/|$//') # Remove trailing '|' 92 | 93 | # Call the search_committee function and store the number of validators found 94 | FOUND_IN_CURRENT=$(search_committee "current" $CURR_EPOCH) 95 | FOUND_IN_NEXT=$(search_committee "next" $NEXT_START_EPOCH) 96 | 97 | # Check the total number of validators found 98 | TOTAL_FOUND=$((FOUND_IN_CURRENT + FOUND_IN_NEXT)) 99 | 100 | # If no validators were found, echo the desired message 101 | if [ $TOTAL_FOUND -eq 0 ]; then 102 | echo "No sync committee duties in this or next epoch found for local validators." 103 | else 104 | echo "Sync committee duties found for local validators in the current and/or next epoch." 105 | fi 106 | 107 | echo "Press [Enter] to exit..." 108 | read 109 | -------------------------------------------------------------------------------- /helper/bls_to_execution.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | start_dir=$(pwd) 4 | script_dir=$(dirname "$0") 5 | source "$script_dir/functions.sh" 6 | check_and_set_network_variables 7 | 8 | sudo apt install jq zenity -y 9 | 10 | # Prompt the user to select the deposit-JSON file using a file dialog 11 | json_file=$(zenity --file-selection --title="Select the deposit-JSON file you wish to exit and scan it for pubkey/bls-withdrawal creds: ") 12 | 13 | # Check if the user selected a file 14 | if [ -z "$json_file" ]; then 15 | echo "No file selected" 16 | exit 1 17 | fi 18 | 19 | # Check if the file exists 20 | if [ ! -f "$json_file" ]; then 21 | echo "File not found" 22 | exit 1 23 | fi 24 | 25 | # Read JSON data from the selected file 26 | json_data=$(cat "$json_file") 27 | 28 | # Get the length of the JSON array 29 | array_length=$(echo "$json_data" | jq 'length') 30 | 31 | # Loop through the array and extract the fields from each object 32 | for ((i=0; i<$array_length; i++)); do 33 | public_key=$(echo "$json_data" | jq -r --argjson index $i '.[$index].pubkey') 34 | withdrawal_credential=$(echo "$json_data" | jq -r --argjson index $i '.[$index].withdrawal_credentials') 35 | echo "" 36 | echo "Public Key: $public_key" 37 | echo "Withdrawal Credential: $withdrawal_credential" 38 | echo "------------------------------------" 39 | echo "" 40 | done 41 | 42 | echo "The following procedure will ask you the following:" 43 | echo "" 44 | echo " - Path to your Blockchain installation" 45 | echo " - Mnemonic you used to create the validator" 46 | echo " - Starting index for the keys you want to convert (usually 0)" 47 | echo " - The Validator index as shown on the pls-beacon-explorer ${LAUNCHPAD_URL}" 48 | echo " - BLS withdrawal-Credentials (starting with 00)" 49 | echo " - The new execution withdrawal wallet" 50 | echo "" 51 | echo "Note: You can enter multiple values, separated with a comma" 52 | echo " You can get your BLS-Withdrawal Credential above or via ${LAUNCHPAD_URL}/en/withdrawals" 53 | echo "" 54 | 55 | read -e -p "Please enter your installation folder (default: /blockchain): " install_path 56 | 57 | # Set the default installation path if the user didn't enter a value 58 | if [ -z "$install_path" ]; then 59 | install_path="/blockchain" 60 | fi 61 | 62 | echo "Getting staking-cli and setting up venv..." 63 | 64 | # Prepare directories 65 | sudo mkdir -p ${install_path}/bls_converter 66 | sudo chmod -R 777 ${install_path}/bls_converter 67 | cd ${install_path}/bls_converter 68 | 69 | # Clone and set up staking-deposit-cli 70 | git clone https://gitlab.com/pulsechaincom/staking-deposit-cli.git > /dev/null 2>&1 71 | cd staking-deposit-cli 72 | 73 | # Create a virtual environment and activate it 74 | python3.8 -m venv venv 75 | source venv/bin/activate 76 | 77 | # Install dependencies in the virtual environment 78 | echo "Installing dependencies..." 79 | pip install --upgrade pip setuptools > /dev/null 2>&1 80 | pip install -r requirements.txt > /dev/null 2>&1 81 | pip install . > /dev/null 2>&1 82 | 83 | # Run staking-deposit-cli command 84 | echo "Running staking-deposit-cli to generate BLS to execution changes..." 85 | ./deposit.sh --language english generate-bls-to-execution-change \ 86 | --chain ${DEPOSIT_CLI_NETWORK} 87 | 88 | # Deactivate the virtual environment 89 | deactivate 90 | 91 | # Move generated files and clean up 92 | echo "Copying over the conversion files..." 93 | sudo mv ${install_path}/bls_converter/staking-deposit-cli/bls_to_execution_changes/*.json ${install_path}/bls_converter/ 94 | cd ${install_path}/bls_converter/ 95 | sudo rm -R staking-deposit-cli 96 | sudo chmod -R 777 *.json 97 | 98 | # Ask to submit changes 99 | read -e -p "Do you wish to submit the bls-to-execution conversion to your beacon now? (y/n):" submit 100 | 101 | if [[ $submit == "y" ]]; then 102 | echo "Please choose your beacon client" 103 | echo "" 104 | echo "1. Lighthouse" 105 | echo "" 106 | echo "2. Prysm" 107 | echo "" 108 | read -e -p "Choose 1 or 2: " client_choice 109 | 110 | if [[ $client_choice == "1" ]]; then 111 | sudo docker run --rm -it \ 112 | -v ${install_path}/bls_converter:/bls_dir \ 113 | --name submit_bls_change \ 114 | --network host \ 115 | registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:latest \ 116 | validator withdraw \ 117 | -beacon-node-host=localhost:5052 \ 118 | --path=/bls_dir \ 119 | --confirm 120 | 121 | elif [[ $client_choice == "2" ]]; then 122 | sudo docker run --rm -it \ 123 | -v ${install_path}/bls_converter:/bls_dir \ 124 | --name submit_bls_change \ 125 | --network host \ 126 | registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:latest \ 127 | validator withdraw \ 128 | -beacon-node-host=localhost:3500 \ 129 | --path=/bls_dir \ 130 | --confirm 131 | fi 132 | else 133 | echo "Don't forget to submit your changes to the network via your beacon..." 134 | read -p "Press enter to continue..." 135 | exit 0 136 | fi 137 | 138 | sudo docker stop submit_bls_change && sudo docker container prune -f 139 | 140 | read -p "Press enter to continue..." 141 | echo "Done" 142 | -------------------------------------------------------------------------------- /helper/show_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # OS version 4 | os_version=$(lsb_release -d | cut -f2) 5 | 6 | # Kernel version 7 | kernel_version=$(uname -r) 8 | 9 | # CPU information 10 | cpu_version=$(grep "model name" /proc/cpuinfo | uniq | cut -d ':' -f2 | sed 's/^ *//') 11 | cores=$(grep -c ^processor /proc/cpuinfo) 12 | threads=$(lscpu | grep 'Thread(s) per core:' | awk '{print $4}') 13 | 14 | # RAM information 15 | total_ram=$(free -h | grep Mem | awk '{print $2}') 16 | used_ram=$(free -h | grep Mem | awk '{print $3}') 17 | free_ram=$(free -h | grep Mem | awk '{print $4}') 18 | 19 | # Disk information 20 | disk_info=$(df -h / | tail -1 | awk '{print $2 " total, " $3 " used, " $4 " free"}') 21 | 22 | # System uptime 23 | uptime_info=$(uptime -p | sed 's/up //') 24 | 25 | clear 26 | echo "General System info: " 27 | echo "-------------------------------------------" 28 | echo "OS Version: $os_version" 29 | echo "Kernel Version: $kernel_version" 30 | echo "CPU: $cpu_version" 31 | echo "Cores: $cores" 32 | echo "Threads: $threads" 33 | echo "Total RAM: $total_ram" 34 | echo "Used RAM: $used_ram" 35 | echo "Free RAM: $free_ram" 36 | echo "Disk Info: $disk_info" 37 | echo "System Uptime: $uptime_info" 38 | echo "-------------------------------------------" 39 | echo "" 40 | 41 | #Prysm-Beacon 42 | version_string=$(docker exec -it beacon /app/cmd/beacon-chain/beacon-chain --version 2>&1) 43 | 44 | if [[ $version_string == *"/"* && $version_string == *" Built at"* ]]; then 45 | # Extract and display Prysm Beacon info... 46 | 47 | 48 | # Extract various components from the string 49 | project_name=$(echo $version_string | cut -d '/' -f1) 50 | version_number=$(echo $version_string | cut -d '/' -f2) 51 | commit_hash=$(echo $version_string | cut -d '/' -f3 | cut -d '.' -f1) 52 | build_date=$(echo $version_string | cut -d ':' -f2- | sed 's/ Built at//') 53 | 54 | # Display the information in a more friendly format 55 | echo "Prysm Beacon info: " 56 | echo "-------------------------------------------" 57 | #echo "Project Name: $project_name" 58 | echo "Version: $version_number" 59 | echo "Commit Hash: $commit_hash" 60 | echo "Build Date: $build_date" 61 | echo "-------------------------------------------" 62 | echo "" 63 | 64 | else 65 | echo "Prysm Beacon: currently not running" 66 | fi 67 | echo "" 68 | 69 | # Prysm-Validator 70 | version_string=$(docker exec -it validator /app/cmd/validator/validator --version 2>&1) 71 | 72 | if [[ $version_string == *"/"* && $version_string == *" Built at"* ]]; then 73 | # Extract and display Prysm Validator info... 74 | 75 | # Extract various components from the string 76 | project_name=$(echo $version_string | cut -d '/' -f1) 77 | version_number=$(echo $version_string | cut -d '/' -f2) 78 | commit_hash=$(echo $version_string | cut -d '/' -f3 | cut -d '.' -f1) 79 | build_date=$(echo $version_string | cut -d ':' -f2- | sed 's/ Built at//') 80 | 81 | # Display the information in a more friendly format 82 | echo "Prysm Validator info: " 83 | echo "-------------------------------------------" 84 | #echo "Project Name: $project_name" 85 | echo "Version: $version_number" 86 | echo "Commit Hash: $commit_hash" 87 | echo "Build Date: $build_date" 88 | echo "-------------------------------------------" 89 | echo "" 90 | else 91 | echo "Prysm Validator: currently not running" 92 | fi 93 | echo "" 94 | 95 | #Lighthouse 96 | lighthouse_info=$(docker exec -it beacon lighthouse beacon_node --version 2>&1) 97 | 98 | # Check if the result contains the expected "lighthouse-beacon_node" pattern 99 | if echo $lighthouse_info | grep -q "lighthouse-beacon_node"; then 100 | # Extract necessary details from the output 101 | lighthouse_version=$(echo $lighthouse_info | sed 's/lighthouse-beacon_node //') 102 | 103 | # Display formatted output 104 | echo "Lighthouse Info: " 105 | echo "-------------------------------------------" 106 | echo "Lighthouse Version: $lighthouse_version" 107 | echo "-------------------------------------------" 108 | echo "" 109 | 110 | else 111 | echo "Lighthouse Beacon Node: currently not running" 112 | fi 113 | # GoPls 114 | version_info=$(docker exec -it execution geth version 2>&1) 115 | 116 | if [[ $version_info == *"Geth"* && $version_info == *"Version:"* ]]; then 117 | # Extract and display GoPls info... 118 | 119 | 120 | 121 | # Extract various components from the string 122 | geth=$(echo "$version_info" | grep "Geth") 123 | version=$(echo "$version_info" | grep "Version" | cut -d ':' -f2 | sed 's/^ *//') 124 | commit=$(echo "$version_info" | grep "Git Commit" | cut -d ':' -f2 | sed 's/^ *//') 125 | commit_date=$(echo "$version_info" | grep "Git Commit Date" | cut -d ':' -f2 | sed 's/^ *//') 126 | architecture=$(echo "$version_info" | grep "Architecture" | cut -d ':' -f2 | sed 's/^ *//') 127 | go_version=$(echo "$version_info" | grep "Go Version" | cut -d ':' -f2 | sed 's/^ *//') 128 | os=$(echo "$version_info" | grep "Operating System" | cut -d ':' -f2 | sed 's/^ *//') 129 | 130 | # Display the information in a more friendly format 131 | echo "GoPls info: " 132 | echo "-------------------------------------------" 133 | echo "Geth: $geth" 134 | echo "Version: $version" 135 | echo "Git Commit: $commit" 136 | echo "Git Commit Date: $commit_date" 137 | echo "Architecture: $architecture" 138 | echo "Go Version: $go_version" 139 | echo "Operating System: $os" 140 | echo "-------------------------------------------" 141 | 142 | else 143 | echo "GoPls (Geth): currently not running" 144 | fi 145 | 146 | echo "" 147 | echo "" 148 | read -p "Press Enter to continue..." 149 | -------------------------------------------------------------------------------- /setup_offline_keygen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | RED='\033[0;31m' 3 | GREEN='\033[0;32m' 4 | NC='\033[0m' # No Color 5 | 6 | clear 7 | 8 | echo "" 9 | echo "" 10 | echo "+-------------------------------------------------------+" 11 | echo "| DipSlayer presents: |" 12 | echo "| |" 13 | echo "| Staking-Cli Offline Setup for |" 14 | echo "| Pulsechain-Mainnet only |" 15 | echo "| |" 16 | echo "+-------------------------------------------------------+" 17 | echo "" 18 | echo "" 19 | echo "Disclaimer:" 20 | echo "" 21 | echo "This script downloads the necessary requirements for running Staking-Cli and" 22 | echo "facilitates the generation of validator keys. It is intended to be used on a" 23 | echo "separate, offline device." 24 | echo "" 25 | echo "Please ensure the following:" 26 | echo "- The device running this script is separate from the validator itself." 27 | echo "- The device is airgapped and disconnected from the network during the key generation process." 28 | echo "- Once the initial setup is complete, the device should remain offline to ensure the security" 29 | echo " of the generated validator keys." 30 | echo "" 31 | echo "Please exercise caution and follow best practices to protect the integrity and security of" 32 | echo "your validator keys." 33 | echo "" 34 | echo "After the initial Setup is done you can launch the Validator-Keygen via the Desktop Icon" 35 | echo "or via the terminal command \"keygen\" from anywhere within your terminal/cli/console" 36 | echo "+-------------------------------------------------------+" 37 | echo "" 38 | echo "Press Enter to Continue" 39 | read -p "" 40 | 41 | function get_main_user() { 42 | main_user=$(logname || echo $SUDO_USER || echo $USER) 43 | echo "Main user: $main_user" 44 | } 45 | 46 | clear 47 | sudo apt-get install -y software-properties-common 48 | sudo add-apt-repository -y universe 49 | sudo apt update 50 | sudo apt install -y git 51 | 52 | 53 | # Step 2: Ensure Python 3.8 is installed 54 | echo "Ensuring Python 3.8 is installed..." 55 | sudo add-apt-repository -y ppa:deadsnakes/ppa 56 | sudo apt-get update 57 | sudo apt-get install -y python3.8 python3.8-venv python3.8-distutils python3.8-dev 58 | 59 | # Verify Python 3.8 installation 60 | #python3.8_version=$(python3.8 -V 2>&1) 61 | #if [[ $python3.8_version != "Python 3.8"* ]]; then 62 | # echo -e "${RED}Error: Python 3.8 is not installed correctly.${NC}" 63 | # exit 1 64 | #fi 65 | echo -e "${GREEN}Python 3.8 is successfully installed.${NC}" 66 | 67 | clear 68 | 69 | # Prompt the user for the installation path 70 | read -e -p "Please enter the installation path (Press Enter for default: ~/stakingcli): " INSTALL_PATH 71 | 72 | # Check if the user has entered a path 73 | if [ -z "$INSTALL_PATH" ]; then 74 | INSTALL_PATH=~/stakingcli 75 | fi 76 | 77 | clear 78 | 79 | echo "Checking if staking-cli is already installed..." 80 | if [ -d "${INSTALL_PATH}" ]; then 81 | while true; do 82 | read -p "The staking-deposit-cli folder already exists. Do you want to delete it and clone the latest version? (y/N): " confirm_delete 83 | if [ "$confirm_delete" == "y" ] || [ "$confirm_delete" == "Y" ]; then 84 | sudo rm -rf "${INSTALL_PATH}" 85 | break 86 | elif [ "$confirm_delete" == "n" ] || [ "$confirm_delete" == "N" ] || [ -z "$confirm_delete" ]; then 87 | echo "Skipping the cloning process as the user chose not to delete the existing folder." 88 | break 89 | else 90 | echo "Invalid option. Please enter 'y' or 'n'." 91 | fi 92 | done 93 | fi 94 | 95 | # Clone the staking-deposit-cli repository 96 | if [ ! -d "${INSTALL_PATH}" ]; then 97 | echo "Cloning the staking-deposit-cli repository..." 98 | git clone https://gitlab.com/pulsechaincom/staking-deposit-cli.git "${INSTALL_PATH}" || { 99 | echo -e "${RED}Failed to clone the repository. Please check your internet connection.${NC}" 100 | exit 1 101 | } 102 | else 103 | echo "Directory already exists. Skipping the cloning process." 104 | fi 105 | 106 | # Step 3: Set up virtual environment 107 | echo "Setting up Python 3.8 virtual environment..." 108 | cd "${INSTALL_PATH}" || exit 109 | python3.8 -m venv venv 110 | source venv/bin/activate 111 | 112 | # Install staking-cli dependencies inside venv 113 | echo "Installing staking-cli dependencies inside the virtual environment..." 114 | pip install --upgrade pip setuptools > /dev/null 2>&1 115 | pip install -r requirements.txt > /dev/null 2>&1 116 | pip install . > /dev/null 2>&1 117 | if [ $? -ne 0 ]; then 118 | echo -e "${RED}Failed to install staking-cli dependencies.${NC}" 119 | deactivate 120 | exit 1 121 | fi 122 | echo -e "${GREEN}Staking-cli dependencies installed successfully inside the virtual environment.${NC}" 123 | 124 | # Keygen script generation 125 | echo "Generating keygen script..." 126 | cat > "${INSTALL_PATH}/offline_key.sh" << EOL 127 | #!/bin/bash 128 | 129 | INSTALL_PATH="${INSTALL_PATH}" 130 | 131 | RED='\033[0;31m' 132 | GREEN='\033[0;32m' 133 | NC='\033[0m' # No Color 134 | 135 | source "\${INSTALL_PATH}/venv/bin/activate" 136 | 137 | generate_new_validator_key() { 138 | clear 139 | echo "Generating new validator keys..." 140 | while true; do 141 | read -e -p "Enter Withdrawal Wallet Address: " withdrawal_wallet 142 | if [[ "\${withdrawal_wallet}" =~ ^0x[a-fA-F0-9]{40}$ ]]; then 143 | break 144 | else 145 | echo "Invalid address format. Please try again." 146 | fi 147 | done 148 | cd "\${INSTALL_PATH}" 149 | ./deposit.sh new-mnemonic \ 150 | --mnemonic_language=english \ 151 | --chain=pulsechain \ 152 | --folder="\${INSTALL_PATH}" \ 153 | --eth1_withdrawal_address="\${withdrawal_wallet}" 154 | } 155 | 156 | restore_from_mnemonic() { 157 | clear 158 | echo "Restoring keys from mnemonic..." 159 | while true; do 160 | read -e -p "Enter Withdrawal Wallet Address: " withdrawal_wallet 161 | if [[ "\${withdrawal_wallet}" =~ ^0x[a-fA-F0-9]{40}$ ]]; then 162 | break 163 | else 164 | echo "Invalid address format. Please try again." 165 | fi 166 | done 167 | cd "\${INSTALL_PATH}" 168 | ./deposit.sh existing-mnemonic \ 169 | --chain=pulsechain \ 170 | --folder="\${INSTALL_PATH}" \ 171 | --eth1_withdrawal_address="\${withdrawal_wallet}" 172 | } 173 | 174 | echo "Choose an option:" 175 | echo "1) Generate new validator keys" 176 | echo "2) Restore keys from mnemonic" 177 | echo "0) Exit" 178 | read choice 179 | 180 | case \$choice in 181 | 1) generate_new_validator_key ;; 182 | 2) restore_from_mnemonic ;; 183 | 0) exit ;; 184 | *) echo "Invalid option." ;; 185 | esac 186 | EOL 187 | 188 | chmod +x "${INSTALL_PATH}/offline_key.sh" 189 | sudo ln -s "${INSTALL_PATH}/offline_key.sh" /usr/local/bin/keygen 190 | 191 | # Desktop shortcut 192 | desktop_file="${HOME}/Desktop/offline_keygen.desktop" 193 | cat > "${desktop_file}" << EOL 194 | [Desktop Entry] 195 | Version=1.0 196 | Type=Application 197 | Name=Offline Keygen 198 | Comment=Generate validator keys offline 199 | Exec=${INSTALL_PATH}/offline_key.sh 200 | Icon=utilities-terminal 201 | Terminal=true 202 | Categories=Utility; 203 | EOL 204 | chmod +x "${desktop_file}" 205 | 206 | # Deactivate virtual environment 207 | deactivate 208 | 209 | clear 210 | echo -e "${GREEN}Setup complete.${NC}" 211 | echo "Run 'keygen' or use the Desktop shortcut to start." 212 | echo "" 213 | echo "" 214 | echo -e "You can launch the validator key setup anytime via the command ${GREEN}keygen${NC} from the terminal, or the Desktop-Icon \"Offline Keygen\"" 215 | echo "you can find the main_script here: ${INSTALL_PATH}/offline_key.sh." 216 | echo "" 217 | echo "Keys will be generated in this folder: ${INSTALL_PATH}/validator_keys" 218 | echo "" 219 | echo "Press Enter to continue" 220 | read -p "" 221 | echo "" 222 | echo "Brought to you by:" 223 | echo "██████__██_██████__███████_██_______█████__██____██_███████_██████__" 224 | echo "██___██_██_██___██_██______██______██___██__██__██__██______██___██_" 225 | echo "██___██_██_██████__███████_██______███████___████___█████___██████__" 226 | echo "██___██_██_██___________██_██______██___██____██____██______██___██_" 227 | echo "██████__██_██______███████_███████_██___██____██____███████_██___██_" 228 | echo "" 229 | 230 | -------------------------------------------------------------------------------- /setup_monitoring.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # v0.5 4 | 5 | #Icosa, Hex, Hedron, 6 | #Three shapes in symmetry dance, 7 | #Nature's art is shown. 8 | 9 | # By tdslaine aka Peter L Dipslayer TG: @dipslayer369 Twitter: @dipslayer 10 | 11 | script_dir=$(dirname "$0") 12 | source "$script_dir/functions.sh" 13 | 14 | start_dir=$(pwd) 15 | GREEN='\033[0;32m' 16 | RED='\033[0;31m' 17 | NC='\033[0m' # No Color 18 | 19 | source "./functions.sh" 20 | 21 | clear 22 | 23 | # Create users 24 | echo "Adding users for prometheus and grafana" 25 | sudo useradd -M -G docker prometheus 26 | sudo useradd -M -G docker grafana 27 | 28 | # Prompt the user for the location to store prometheus.yml (default: /blockchain) 29 | read -e -p "Enter the location to store prometheus.yml (default: /blockchain):" config_location 30 | config_location=$(echo "$config_location" | sed 's:/*$::') 31 | 32 | # Set the default location to /blockchain if nothing is entered 33 | if [ -z "$config_location" ]; then 34 | config_location="/blockchain" 35 | fi 36 | 37 | while true; do 38 | echo "Choose your Client" 39 | echo "" 40 | echo "1. Lighthouse" 41 | echo "2. Prysm" 42 | echo "" 43 | read -p "Enter your choice (1 or 2): " client_choice 44 | 45 | case $client_choice in 46 | 1|2) 47 | break 48 | ;; 49 | *) 50 | echo "Invalid choice. Please enter 1 or 2." 51 | ;; 52 | esac 53 | done 54 | 55 | echo $client_choice 56 | 57 | 58 | # Create directories 59 | echo "" 60 | echo "Creating directorys for the prometheus and grafana container" 61 | sudo mkdir -p "$config_location/prometheus" 62 | sudo mkdir -p "$config_location/grafana" 63 | 64 | if [[ "$client_choice" == "1" ]]; then 65 | 66 | # Define the yml content for use with lighthouse 67 | PROMETHEUS_YML="global: 68 | scrape_interval: 15s 69 | evaluation_interval: 15s 70 | scrape_configs: 71 | - job_name: 'node_exporter' 72 | static_configs: 73 | - targets: ['localhost:9100'] 74 | - job_name: 'nodes' 75 | metrics_path: /metrics 76 | static_configs: 77 | - targets: ['localhost:5054'] 78 | - job_name: 'validators' 79 | metrics_path: /metrics 80 | static_configs: 81 | - targets: ['localhost:5064'] 82 | - job_name: 'geth' 83 | scrape_interval: 15s 84 | scrape_timeout: 10s 85 | metrics_path: /debug/metrics/prometheus 86 | scheme: http 87 | static_configs: 88 | - targets: ['localhost:6060']" 89 | 90 | elif [[ "$client_choice" == "2" ]]; then 91 | PROMETHEUS_YML="global: 92 | scrape_interval: 15s # By default, scrape targets every 15 seconds. 93 | 94 | # Attach these labels to any time series or alerts when communicating with 95 | # external systems (federation, remote storage, Alertmanager). 96 | external_labels: 97 | monitor: 'codelab-monitor' 98 | 99 | # A scrape configuration containing exactly one endpoint to scrape: 100 | # Here it's Prometheus itself. 101 | scrape_configs: 102 | - job_name: 'node_exporter' 103 | static_configs: 104 | - targets: ['localhost:9100'] 105 | - job_name: 'validator' 106 | static_configs: 107 | - targets: ['localhost:8081'] 108 | - job_name: 'beacon node' 109 | static_configs: 110 | - targets: ['localhost:8080'] 111 | - job_name: 'slasher' 112 | static_configs: 113 | - targets: ['localhost:8082'] 114 | - job_name: 'geth' 115 | scrape_interval: 15s 116 | scrape_timeout: 10s 117 | metrics_path: /debug/metrics/prometheus 118 | scheme: http 119 | static_configs: 120 | - targets: ['localhost:6060']" 121 | fi 122 | 123 | # Create prometheus.yml file 124 | echo "" 125 | echo "Creating the yml file for promethesu" 126 | sudo bash -c "cat > $config_location/prometheus.yml << 'EOF' 127 | $PROMETHEUS_YML 128 | EOF" 129 | 130 | # Set ownership and permissions 131 | echo "" 132 | echo "Setting ownership for container-folders" 133 | sudo chown -R prometheus:prometheus "$config_location/prometheus" 134 | sudo chown -R grafana:grafana "$config_location/grafana" 135 | sudo chmod 644 "$config_location/prometheus.yml" 136 | sudo chmod -R 777 "$config_location/grafana" 137 | 138 | # Set UFW Rules 139 | echo "" 140 | echo "Setting up firewall rules to allow local connection to metric ports" 141 | sudo ufw allow from 127.0.0.1 to any port 8545 proto tcp 142 | sudo ufw allow from 127.0.0.1 to any port 8546 proto tcp 143 | 144 | if [[ "$client_choice" == "1" ]]; then 145 | sudo ufw allow from 127.0.0.1 to any port 5052 proto tcp 146 | sudo ufw allow from 127.0.0.1 to any port 5064 proto tcp 147 | 148 | elif [[ "$client_choice" == "2" ]]; then 149 | sudo ufw allow from 127.0.0.1 to any port 8081 proto tcp 150 | sudo ufw allow from 127.0.0.1 to any port 8080 proto tcp 151 | sudo ufw allow from 127.0.0.1 to any port 8082 proto tcp 152 | fi 153 | # Prompt to allow access to Grafana Dashboard in Local Network 154 | 155 | function get_local_ip() { 156 | local_ip=$(hostname -I | awk '{print $1}') 157 | echo $local_ip 158 | } 159 | 160 | function get_ip_range() { 161 | local_ip=$(get_local_ip) 162 | ip_parts=(${local_ip//./ }) 163 | ip_range="${ip_parts[0]}.${ip_parts[1]}.${ip_parts[2]}.0/24" 164 | echo $ip_range 165 | } 166 | 167 | #debug 168 | local_ip_debug=$(hostname -I | awk '{print $1}') 169 | ip_range=$(get_ip_range) 170 | 171 | echo "" 172 | echo "Your Current IP is: $local_ip_debug" 173 | echo "" 174 | read -p "Do you want to allow access to the Grafana Dashboard from within your local network ($ip_range)? (y/n): " local_network_choice 175 | echo "" 176 | 177 | if [[ $local_network_choice == "y" ]]; then 178 | echo "" 179 | sudo ufw allow from $ip_range to any port 3000 proto tcp comment 'Grafana Port for private IP range' 180 | 181 | fi 182 | 183 | echo "" 184 | sudo ufw reload 185 | echo "" 186 | 187 | # Define Docker commands as variables 188 | PROMETHEUS_CMD="sudo -u prometheus docker run -dt --name prometheus --restart=always \\ 189 | --net='host' \\ 190 | -v ${config_location}/prometheus.yml:/prometheus/prometheus.yml \\ 191 | -v ${config_location}/prometheus:/prometheus-data \\ 192 | prom/prometheus \\ 193 | --web.listen-address='0.0.0.0:9099' 194 | " 195 | 196 | PROMETHEUS_NODE_CMD="sudo -u prometheus docker run -dt --name node_exporter --restart=always \\ 197 | --net='host' \\ 198 | -v '/:/host:ro,rslave' \\ 199 | prom/node-exporter --path.rootfs=/host 200 | 201 | " 202 | 203 | GRAFANA_CMD="sudo -u grafana docker run -dt --name grafana --restart=always \\ 204 | --net='host' \\ 205 | -v ${config_location}/grafana:/var/lib/grafana \\ 206 | grafana/grafana 207 | 208 | " 209 | 210 | # Create start_monitoring.sh script 211 | echo "" 212 | echo "Creating start_monitor.sh script" 213 | sudo bash -c "cat > $config_location/start_monitoring.sh << 'EOF' 214 | #!/bin/bash 215 | 216 | $PROMETHEUS_CMD 217 | $PROMETHEUS_NODE_CMD 218 | $GRAFANA_CMD 219 | EOF" 220 | 221 | get_main_user 222 | # Make start_monitoring.sh executable 223 | sudo chmod +x $config_location/start_monitoring.sh 224 | sudo chmod 770 $config_location/start_monitoring.sh 225 | sudo chown $main_user:docker $config_location/start_monitoring.sh 226 | 227 | echo "" 228 | echo "Created Monitoring-Scripts and Set Firewall rules" 229 | cd $config_location 230 | echo "..." 231 | sleep 2 232 | 233 | echo "" 234 | echo "Launching prometheus, node-exporter and grafana containers" 235 | echo "" 236 | sudo $config_location/start_monitoring.sh 237 | sleep 2 238 | 239 | # checking if they are running 240 | echo "" 241 | echo "Checking if the docker started" 242 | echo "" 243 | if sudo docker ps --format '{{.Names}}' | grep -q '^grafana$'; then 244 | echo "Grafana container is running" 245 | else 246 | echo "Grafana container is not running" 247 | fi 248 | echo "" 249 | if sudo docker ps --format '{{.Names}}' | grep -q '^prometheus$'; then 250 | echo "Prometheus container is running" 251 | else 252 | echo "Prometheus container is not running" 253 | fi 254 | echo "" 255 | if sudo docker ps --format '{{.Names}}' | grep -q '^node_exporter$'; then 256 | echo "Node Exporter container is running" 257 | else 258 | echo "Node Exporter container is not running" 259 | fi 260 | echo "" 261 | 262 | sleep 2 263 | 264 | # Set variables for the API endpoint, authentication, and datasource configuration 265 | grafana_api="http://localhost:3000/api/datasources" 266 | grafana_auth="admin:admin" 267 | prometheus_url="http://localhost:9099" 268 | datasource_name="Prometheus" 269 | datasource_type="prometheus" 270 | access_mode="proxy" 271 | basic_auth_user="" 272 | basic_auth_password="" 273 | is_default="true" 274 | 275 | # Send the POST request to add the datasource using curl 276 | curl -X POST -H "Content-Type: application/json" -d \ 277 | '{ 278 | "name": "'$datasource_name'", 279 | "type": "'$datasource_type'", 280 | "url": "'$prometheus_url'", 281 | "access": "'$access_mode'", 282 | "basicAuthUser": "'$basic_auth_user'", 283 | "basicAuthPassword": "'$basic_auth_password'", 284 | "isDefault": '$is_default' 285 | }' \ 286 | --user "$grafana_auth" \ 287 | $grafana_api 288 | 289 | sleep 1 290 | echo "" 291 | 292 | sudo mkdir -p "${config_location}/Dashboards" 293 | echo "Downloading dashboard JSON..." 294 | sudo wget -qO "${config_location}/Dashboards/002_Geth_dashboard.json" -P "${config_location}/Dashboards" https://gist.githubusercontent.com/karalabe/e7ca79abdec54755ceae09c08bd090cd/raw/dashboard.json >/dev/null 295 | sudo wget -qO "${config_location}/Dashboards/003_System_dashboard.json" -P "${config_location}/Dashboards" https://grafana.com/api/dashboards/11074/revisions/9/download >/dev/null 296 | 297 | if [[ "$client_choice" == "1" ]]; then 298 | sudo wget -O "${config_location}/Dashboards/004_Lighthouse_beacon_dashboard.json" -P "${config_location}/Dashboards" https://raw.githubusercontent.com/sigp/lighthouse-metrics/master/dashboards/Summary.json >/dev/null 299 | sudo wget -O "${config_location}/Dashboards/005_Lighthouse_validator_dashboard.json" -P "${config_location}/Dashboards" https://raw.githubusercontent.com/sigp/lighthouse-metrics/master/dashboards/ValidatorClient.json 300 | sudo wget -O "${config_location}/Dashboards/001_Staking_dashboard.json" -P "${config_location}/Dashboards" https://raw.githubusercontent.com/tdslaine/pulse-staking-dashboard/main/Yoldark_ETH_staking_dashboard.json 301 | 302 | elif [[ "$client_choice" == "2" ]]; then 303 | sudo wget -qO "${config_location}/Dashboards/001_Prysm_dashboard.json" -P "${config_location}/Dashboards" https://raw.githubusercontent.com/GuillaumeMiralles/prysm-grafana-dashboard/master/less_10_validators.json >/dev/null 304 | sudo wget -qO "${config_location}/Dashboards/000_Prysm_dashboard.json" -P "${config_location}/Dashboards" https://raw.githubusercontent.com/metanull-operator/eth2-grafana/master/eth2-grafana-dashboard-single-source-beacon_node.json >/dev/null 305 | 306 | fi 307 | get_main_user 308 | echo "" 309 | echo "" 310 | get_main_user 311 | sudo chown -R $main_user:docker "${config_location}/Dashboards" 312 | sudo chmod -R 777 "${config_location}/Dashboards" 313 | 314 | echo "" 315 | echo -e "${GREEN}Congratulations, setup is now complete.${NC}" 316 | echo "" 317 | if [[ $local_network_choice == "y" ]]; then 318 | echo "Access Grafana: http://127.0.0.1:3000 or http://${local_ip_debug}:3000" 319 | echo "Username: admin" 320 | echo "Password: admin" 321 | echo "" 322 | echo "Add dashboards via: http://127.0.0.1:3000/dashboard/import or http://${local_ip_debug}:3000/dashboard/import" 323 | echo "Import JSONs from '${config_location}/Dashboards'" 324 | else 325 | echo "Access Grafana: http://127.0.0.1:3000" 326 | echo "Username: admin" 327 | echo "Password: admin" 328 | echo "" 329 | echo "Add dashboards via: http://127.0.0.1:3000/dashboard/import" 330 | echo "Import JSONs from '${config_location}/Dashboards'" 331 | echo "" 332 | echo "It is adviced to reboot your system after the initial setup has taken place" 333 | fi 334 | echo "" 335 | echo "Brought to you by: 336 | ██████__██_██████__███████_██_______█████__██____██_███████_██████__ 337 | ██___██_██_██___██_██______██______██___██__██__██__██______██___██_ 338 | ██___██_██_██████__███████_██______███████___████___█████___██████__ 339 | ██___██_██_██___________██_██______██___██____██____██______██___██_ 340 | ██████__██_██______███████_███████_██___██____██____███████_██___██_" 341 | sleep 1 342 | echo "" 343 | echo "Press enter to continue..." 344 | read -p "" 345 | echo "" 346 | read -e -p "$(echo -e "${GREEN}Would you like to start the logviewer to monitor the client logs? [y/n]:${NC}")" log_it 347 | 348 | if [[ "$log_it" =~ ^[Yy]$ ]]; then 349 | echo "Choose a log viewer:" 350 | echo "1. GUI/TAB Based Logviewer (serperate tabs; easy)" 351 | echo "2. TMUX Logviewer (AIO logs; advanced)" 352 | 353 | read -p "Enter your choice (1 or 2): " choice 354 | 355 | case $choice in 356 | 1) 357 | ${config_location}/helper/log_viewer.sh 358 | ;; 359 | 2) 360 | ${config_location}/helper/tmux_logviewer.sh 361 | ;; 362 | *) 363 | echo "Invalid choice. Exiting." 364 | ;; 365 | esac 366 | fi 367 | reboot_prompt 368 | sleep 5 369 | reboot_advice 370 | exit 0 371 | -------------------------------------------------------------------------------- /helper/key_mgmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | start_dir=$(pwd) 4 | script_dir=$(dirname "$0") 5 | GREEN='\033[0;32m' 6 | RED='\033[0;31m' 7 | NC='\033[0m' 8 | 9 | source "$script_dir/functions.sh" 10 | 11 | get_main_user 12 | tab_autocomplete 13 | check_and_set_network_variables 14 | get_install_path 15 | 16 | # Set up Python 3.8 virtual environment 17 | #function setup_python_venv() { 18 | # # Check if Python 3.8 is already installed 19 | # if command -v python3.8 >/dev/null 2>&1; then 20 | # echo "Python 3.8 is already installed." 21 | # else 22 | # echo "Python 3.8 not found. Installing Python 3.8..." 23 | # sudo apt-get install -y software-properties-common 24 | # sudo add-apt-repository -y ppa:deadsnakes/ppa 25 | # sudo apt-get update 26 | # sudo apt-get install -y python3.8 python3.8-venv python3.8-distutils python3.8-dev 27 | 28 | # Verify Python 3.8 installation 29 | #python3.8_version=$(python3.8 -V 2>&1) 30 | #if [[ $python3.8_version != "Python 3.8"* ]]; then 31 | # echo -e "${RED}Error: Python 3.8 is not installed correctly.${NC}" 32 | # exit 1 33 | #fi 34 | # fi 35 | 36 | # Create venv if it doesn't exist 37 | # if [ ! -d "${INSTALL_PATH}/staking-deposit-cli/venv" ]; then 38 | # echo "Creating virtual environment..." 39 | # cd "${INSTALL_PATH}/staking-deposit-cli" || exit 40 | # python3.8 -m venv venv 41 | # else 42 | # echo "Virtual environment already exists." 43 | # fi 44 | 45 | # Activate venv and install dependencies 46 | # source "${INSTALL_PATH}/staking-deposit-cli/venv/bin/activate" 47 | # echo "Installing dependencies inside virtual environment..." 48 | # pip install --upgrade pip setuptools > /dev/null 2>&1 49 | # pip install -r requirements.txt > /dev/null 2>&1 50 | # pip install . > /dev/null 2>&1 51 | # deactivate 52 | # echo -e "${GREEN}Python 3.8 virtual environment setup complete.${NC}" 53 | #} 54 | 55 | function setup_python_venv() { 56 | # Check if the virtual environment already exists 57 | if [ -d "${INSTALL_PATH}/staking-deposit-cli/venv" ]; then 58 | read -p "Virtual environment already exists. Do you want to reset it? (y/N): " choice 59 | choice=${choice:-n} # Default to 'n' if the user just presses enter 60 | if [[ "$choice" =~ ^[Yy]$ ]]; then 61 | echo "Resetting the virtual environment..." 62 | sudo rm -rf "${INSTALL_PATH}/staking-deposit-cli/venv" 63 | else 64 | echo "Skipping setup." 65 | return 66 | fi 67 | fi 68 | 69 | echo "Creating virtual environment..." 70 | 71 | # Install Python 3.8 72 | echo "Installing Python 3.8..." 73 | sudo apt-get install -y software-properties-common 74 | sudo add-apt-repository -y ppa:deadsnakes/ppa 75 | sudo apt-get update 76 | sudo apt-get install -y python3.8 python3.8-venv python3.8-distutils python3.8-dev 77 | 78 | # Create the virtual environment 79 | cd "${INSTALL_PATH}/staking-deposit-cli" || exit 80 | python3.8 -m venv venv 81 | 82 | # Activate venv and install dependencies 83 | source "${INSTALL_PATH}/staking-deposit-cli/venv/bin/activate" 84 | sudo chmod -R 777 "${INSTALL_PATH}/staking-deposit-cli" 85 | echo "Installing dependencies inside virtual environment..." 86 | pip install --upgrade pip setuptools > /dev/null 2>&1 87 | pip install -r requirements.txt > /dev/null 2>&1 88 | pip install . > /dev/null 2>&1 89 | deactivate 90 | 91 | echo -e "${GREEN}Python 3.8 staking CLI virtual environment setup complete.${NC}" 92 | } 93 | # Call the function 94 | 95 | setup_python_venv 96 | 97 | function get_user_choices() { 98 | echo "" 99 | echo "+--------------------------------------------+" 100 | echo "| Choose your Validator Client |" 101 | echo "| |" 102 | echo "| (based on your consensus/beacon Client) |" 103 | echo "+--------------------------------------------+" 104 | echo "| 1. Lighthouse |" 105 | echo "| |" 106 | echo "| 2. Prysm |" 107 | echo "+--------------------------------------------+" 108 | echo "| 0. Return or Exit |" 109 | echo "+--------------------------------------------+" 110 | 111 | echo "" 112 | read -p "Enter your choice (1, 2 or 0): " client_choice 113 | 114 | # Validate user input for client choice 115 | while [[ ! "$client_choice" =~ ^[0-2]$ ]]; do 116 | echo "Invalid input. Please enter a valid choice (1, 2 or 0): " 117 | read -p "Enter your choice (1, 2 or 0): " client_choice 118 | done 119 | 120 | if [[ "$client_choice" == "0" ]]; then 121 | echo "Exiting..." 122 | exit 0 123 | fi 124 | } 125 | get_user_choices 126 | 127 | 128 | 129 | generate_new_validator_key() { 130 | source "${INSTALL_PATH}/staking-deposit-cli/venv/bin/activate" 131 | 132 | if [[ "$client_choice" == "1" ]]; then 133 | check_and_pull_lighthouse 134 | elif [[ "$client_choice" == "2" ]]; then 135 | check_and_pull_prysm_validator 136 | fi 137 | 138 | echo "Adding into an existing setup requires all running validator-clients to stop. This action will take place now." 139 | press_enter_to_continue 140 | stop_docker_container "validator" >/dev/null 2>&1 141 | 142 | warn_network 143 | clear 144 | 145 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 146 | network_interface_DOWN 147 | fi 148 | 149 | echo "" 150 | echo "Generating the validator keys via staking-cli" 151 | echo "" 152 | echo "Please follow the instructions and make sure to READ! and understand everything on screen" 153 | echo "" 154 | echo -e "${RED}Attention:${NC}" 155 | echo "" 156 | echo "The next step requires you to enter the wallet address that you would like to use for receiving" 157 | echo "validator rewards while validating and withdrawing your funds when you exit the validator pool." 158 | echo -e "This is the ${GREEN}Withdrawal- or Execution-Wallet (they are the same)${NC}" 159 | echo "" 160 | echo -e "Make sure ${RED}you have full access${NC} to this Wallet. ${RED}Once set, it cannot be changed${NC}" 161 | echo "" 162 | echo -e "You need to provide this Wallet-Adresss in the ${GREEN}proper format (checksum)${NC}." 163 | echo -e "One way to achive this, is to copy your adress from the Blockexplorer" 164 | echo "" 165 | if confirm_prompt "I have read this information and confirm that I understand the importance of using the right Withdrawal-Wallet Address."; then 166 | echo "" 167 | echo "proceeding..." 168 | sleep 2 169 | else 170 | echo "Exiting script now." 171 | network_interface_UP 172 | exit 1 173 | fi 174 | 175 | 176 | echo "" 177 | 178 | # Check if the address is a valid address, loop until it is... 179 | while true; do 180 | read -e -p "Please enter your Execution/Withdrawal-Wallet address: " withdrawal_wallet 181 | if [[ "${withdrawal_wallet}" =~ ^0x[a-fA-F0-9]{40}$ ]]; then 182 | break 183 | else 184 | echo "Invalid address format. Please enter a valid PRC20 address." 185 | fi 186 | done 187 | 188 | 189 | # Running staking-cli to Generate the new validator_keys 190 | echo "" 191 | echo "Starting staking-cli to Generate the new validator_keys" 192 | echo "" 193 | 194 | cd "${INSTALL_PATH}" 195 | sudo chmod -R 777 "${INSTALL_PATH}/validator_keys" >/dev/null 2>&1 196 | sudo chmod -R 777 "${INSTALL_PATH}/wallet" >/dev/null 2>&1 197 | 198 | 199 | cd ${INSTALL_PATH}/staking-deposit-cli 200 | ./deposit.sh new-mnemonic \ 201 | --mnemonic_language=english \ 202 | --chain=${DEPOSIT_CLI_NETWORK} \ 203 | --folder="${INSTALL_PATH}" \ 204 | --eth1_withdrawal_address="${withdrawal_wallet}" 205 | 206 | deactivate 207 | 208 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 209 | network_interface_UP 210 | fi 211 | 212 | if [[ "$client_choice" == "1" ]]; then 213 | import_lighthouse_validator 214 | elif [[ "$client_choice" == "2" ]]; then 215 | import_prysm_validator 216 | fi 217 | 218 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "keystore*.json" -exec sudo chmod 440 {} \; 219 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "deposit*.json" -exec sudo chmod 444 {} \; 220 | sudo find "$INSTALL_PATH/validator_keys" -type f -exec sudo chown $main_user:pls-validator {} \; 221 | 222 | 223 | 224 | start_script ../start_validator 225 | 226 | echo "" 227 | sudo chmod -R 777 "${INSTALL_PATH}/validator_keys" 228 | echo "Import into existing Setup done." 229 | restart_tmux_logs_session 230 | press_enter_to_continue 231 | exit 0 232 | 233 | } 234 | 235 | ################################################### Import ################################################## 236 | import_restore_validator_keys() { 237 | 238 | 239 | if [[ "$client_choice" == "1" ]]; then 240 | check_and_pull_lighthouse 241 | elif [[ "$client_choice" == "2" ]]; then 242 | check_and_pull_prysm_validator 243 | fi 244 | 245 | echo "Importing into an existing setup requires all running validator-clients to stop. This action will take place now." 246 | press_enter_to_continue 247 | stop_docker_container "validator" >/dev/null 2>&1 248 | 249 | 250 | 251 | clear 252 | # Prompt the user to enter the path where their keystore files are located 253 | echo -e "Enter the path where your 'keystore*.json' files are located." 254 | echo -e "For example, if your files are located in '/home/user/my_keys', provide the path '/home/user/my_keys'." 255 | echo -e "You can use tab-autocomplete when entering the path." 256 | echo "" 257 | read -e -p "Path to your keys: " keys_path 258 | # Remove trailing slashes from the path 259 | keys_path="${keys_path%/}" 260 | 261 | 262 | echo "" 263 | echo "Importing validator keys now" 264 | echo "" 265 | 266 | #sudo chmod -R 770 "${INSTALL_PATH}/validator_keys" >/dev/null 2>&1 267 | sudo chmod -R 770 "${INSTALL_PATH}/wallet" >/dev/null 2>&1 268 | 269 | if [[ "$client_choice" == "1" ]]; then 270 | # Base command 271 | cmd="sudo docker run -it \ 272 | --name validator_import \ 273 | --network=host \ 274 | -v ${INSTALL_PATH}:/blockchain \ 275 | -v ${keys_path}:/keys \ 276 | registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest \ 277 | lighthouse \ 278 | --network=${LIGHTHOUSE_NETWORK_FLAG} \ 279 | account validator import \ 280 | --directory=/keys \ 281 | --datadir=/blockchain" 282 | 283 | # Execute the Docker command or handle error 284 | eval $cmd || echo "Error during Lighthouse import" 285 | 286 | elif [[ "$client_choice" == "2" ]]; then 287 | 288 | sudo chmod -R 0600 "${INSTALL_PATH}/wallet/direct/accounts/all-accounts.keystore.json" 289 | 290 | docker_cmd="docker run --rm -it \ 291 | --name validator_import \ 292 | -v ${keys_path}:/keys \ 293 | -v $INSTALL_PATH/wallet:/wallet \ 294 | registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest \ 295 | accounts import \ 296 | --${PRYSM_NETWORK_FLAG} \ 297 | --keys-dir=/keys \ 298 | --wallet-dir=/wallet \ 299 | --wallet-password-file=/wallet/pw.txt" 300 | 301 | # Execute the Docker command or handle error 302 | eval $docker_cmd || echo "Error during Prysm import" 303 | fi 304 | 305 | #sudo find "$INSTALL_PATH/validator_keys" -type f -name "keystore*.json" -exec sudo chmod 440 {} \; 306 | #sudo find "$INSTALL_PATH/validator_keys" -type f -name "deposit*.json" -exec sudo chmod 444 {} \; 307 | #sudo find "$INSTALL_PATH/validator_keys" -type f -exec sudo chown $main_user:pls-validator {} \; 308 | 309 | 310 | 311 | start_script ../start_validator 312 | 313 | echo "" 314 | #sudo chmod 550 "${INSTALL_PATH}/validator_keys" 315 | echo "Import into existing Setup done." 316 | restart_tmux_logs_session 317 | press_enter_to_continue 318 | exit 0 319 | 320 | } 321 | 322 | ################################################### Restore ################################################## 323 | # Function to restore from SeedPhrase 324 | Restore_from_MN() { 325 | source "${INSTALL_PATH}/staking-deposit-cli/venv/bin/activate" 326 | echo "Restoring validator_keys from SeedPhrase (Mnemonic)" 327 | 328 | if [[ "$client_choice" == "1" ]]; then 329 | check_and_pull_lighthouse 330 | elif [[ "$client_choice" == "2" ]]; then 331 | check_and_pull_prysm_validator 332 | fi 333 | 334 | echo "Importing into an existing setup requires all running validator-clients to stop. This action will take place now." 335 | press_enter_to_continue 336 | stop_docker_container "validator" >/dev/null 2>&1 337 | 338 | clear 339 | 340 | warn_network 341 | 342 | clear 343 | 344 | 345 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 346 | network_interface_DOWN 347 | fi 348 | # Check if the address is a valid address, loop until it is... 349 | while true; do 350 | read -e -p "Please enter your Execution/Withdrawal-Wallet address: " withdrawal_wallet 351 | if [[ "${withdrawal_wallet}" =~ ^0x[a-fA-F0-9]{40}$ ]]; then 352 | break 353 | else 354 | echo "Invalid address format. Please enter a valid PRC20 address." 355 | fi 356 | done 357 | 358 | 359 | echo "" 360 | echo "Now running staking-cli command to restore from your SeedPhrase (Mnemonic)" 361 | echo "" 362 | 363 | cd "${INSTALL_PATH}" 364 | sudo chmod -R 777 "${INSTALL_PATH}/validator_keys" >/dev/null 2>&1 365 | sudo chmod -R 777 "${INSTALL_PATH}/wallet" >/dev/null 2>&1 366 | 367 | cd ${INSTALL_PATH}/staking-deposit-cli/ 368 | ./deposit.sh existing-mnemonic \ 369 | --chain=${DEPOSIT_CLI_NETWORK} \ 370 | --folder="${INSTALL_PATH}" \ 371 | --eth1_withdrawal_address="${withdrawal_wallet}" 372 | 373 | deactivate 374 | 375 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 376 | network_interface_UP 377 | fi 378 | 379 | if [[ "$client_choice" == "1" ]]; then 380 | import_lighthouse_validator 381 | elif [[ "$client_choice" == "2" ]]; then 382 | import_prysm_validator 383 | 384 | fi 385 | 386 | sudo chmod -R 770 "${INSTALL_PATH}/validator_keys" 387 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "keystore*.json" -exec sudo chmod 770 {} \; 388 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "deposit*.json" -exec sudo chmod 774 {} \; 389 | sudo find "$INSTALL_PATH/validator_keys" -type f -exec sudo chown $main_user:pls-validator {} \; 390 | 391 | 392 | 393 | start_script ../start_validator 394 | 395 | echo "" 396 | echo "Import into existing Setup done." 397 | #sudo chmod -R 770 "${INSTALL_PATH}/validator_keys" 398 | restart_tmux_logs_session 399 | press_enter_to_continue 400 | exit 0 401 | } 402 | 403 | 404 | 405 | # Selection menu 406 | echo "-----------------------------------------" 407 | echo "| Validator Key Setup |" 408 | echo "-----------------------------------------" 409 | echo "" 410 | PS3=$'\nChoose an option (1-4): ' 411 | options=("Generate new validator_keys (fresh)" "Import/Restore validator_keys from a Folder (from Offline generation or Backup)" "Restore or Add from a Seed Phrase (Mnemonic) " "Exit/Cancel") 412 | COLUMNS=1 413 | select opt in "${options[@]}" 414 | 415 | do 416 | case $REPLY in 417 | 1) 418 | generate_new_validator_key 419 | break 420 | ;; 421 | 2) 422 | import_restore_validator_keys 423 | break 424 | ;; 425 | 3) 426 | Restore_from_MN 427 | break 428 | ;; 429 | 430 | 4) 431 | echo "Exiting..." 432 | exit 0 433 | ;; 434 | *) 435 | echo "Invalid option. Please choose option (1-4)." 436 | ;; 437 | esac 438 | done 439 | -------------------------------------------------------------------------------- /helper/backup_restore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Prompt for sudo password at the start and keep the session alive 4 | sudo -v 5 | # Refresh sudo session in the background 6 | while true; do 7 | sudo -v 8 | sleep 300 9 | done & 10 | SUDO_KEEP_ALIVE_PID=$! 11 | 12 | trap 'cleanup_and_exit' INT 13 | 14 | function cleanup_and_exit() { 15 | echo "Interrupted. Cleaning up..." 16 | start_docker 17 | kill $SUDO_KEEP_ALIVE_PID 18 | exit 1 19 | } 20 | 21 | #debug helper 22 | #set -x 23 | 24 | # Setup variables 25 | DEFAULT_INSTALL_PATH=/blockchain 26 | DATE=$(date +"%Y%m%d%H%M") 27 | 28 | function get_main_user() { 29 | main_user=$(sudo logname || echo $SUDO_USER || echo $USER) 30 | export main_user 31 | echo "Main user: $main_user" 32 | } 33 | 34 | # Check for pigz installation and install if necessary 35 | if ! command -v pigz &>/dev/null; then 36 | echo "pigz is not installed. Attempting to install..." 37 | sudo apt update && sudo apt install tar pigz 38 | fi 39 | 40 | # Menu 41 | function menu() { 42 | clear 43 | echo "" 44 | get_main_user 45 | echo "" 46 | echo "---------------------------------------" 47 | echo "| BACKUP and RESTORE for go-pls |" 48 | echo "---------------------------------------" 49 | echo "| |" 50 | echo "| 1) Backup Chaindata |" 51 | echo "| |" 52 | echo "| 2) Restore Chaindata |" 53 | echo "| |" 54 | echo "---------------------------------------" 55 | 56 | echo "" 57 | echo -n "Please enter a choice [1 - 2] " 58 | read choice 59 | 60 | case $choice in 61 | 1) backup ;; 62 | 2) restore ;; 63 | *) echo "Invalid option" ;; 64 | esac 65 | } 66 | 67 | # Info Function 68 | function info() { 69 | echo "" 70 | echo " Note:" 71 | echo " =====================================================" 72 | echo " # If you're planning to store your backup #" 73 | echo " # on a USB drive, note the following: #" 74 | echo " =====================================================" 75 | echo " =====================================================" 76 | echo " USB Mount Points:" 77 | echo " -----------------------------------------------------" 78 | echo " /media/$main_user/ " 79 | echo " /media/$main_user/ " 80 | echo " -----------------------------------------------------" 81 | echo " Replace with the label of your " 82 | echo " USB drive. If the drive does not have a label, " 83 | echo " it will be its UUID. " 84 | echo " -----------------------------------------------------" 85 | echo " Ensure your USB drive is formatted with a " 86 | echo " filesystem compatible with Linux, such as ext4 " 87 | echo " or NTFS. Other filesystems might not support " 88 | echo " file sizes large enough for the backup. " 89 | echo " -----------------------------------------------------" 90 | echo " Also, confirm the drive has enough space " 91 | echo " for your backup. " 92 | echo "------------------------------------------------------" 93 | echo " If you have enough space on your drive you are " 94 | echo " able to create the backup to your local storage " 95 | echo " too " 96 | echo " =====================================================" 97 | echo "" 98 | } 99 | 100 | function backup() { 101 | read -e -p "Please enter your main install path (default: /blockchain): " INSTALL_PATH 102 | INSTALL_PATH=$(readlink -m "${INSTALL_PATH:-$DEFAULT_INSTALL_PATH}") 103 | 104 | # add folder structure 105 | CHAINDATA="$INSTALL_PATH/execution/geth/geth/chaindata" 106 | echo "$CHAINDATA" 107 | 108 | while true; do 109 | info 110 | read -e -p "Please enter the target location for your backup (Tab-autocomplete is supported): " BACKUP_LOCATION 111 | BACKUP_LOCATION=$(readlink -m "${BACKUP_LOCATION%/}") 112 | if [ -d "$BACKUP_LOCATION" ]; then 113 | break 114 | else 115 | echo "The directory does not exist." 116 | read -p "Do you want to create it? (y/n)" create_dir 117 | if [ "$create_dir" != "${create_dir#[Yy]}" ]; then 118 | sudo mkdir -p "$BACKUP_LOCATION" 119 | sudo chown $main_user:$main_user "$BACKUP_LOCATION" 120 | sudo chmod -R 777 "$BACKUP_LOCATION" 121 | else 122 | echo "Please enter a valid directory." 123 | fi 124 | fi 125 | done 126 | 127 | read -p "Warning: The Execution-Client will be stopped and resumed after the backup is complete. Do you want to continue? (y/n)" answer 128 | if [ "$answer" != "${answer#[Yy]}" ]; then 129 | echo "" 130 | trap sigint_handler_backup INT 131 | stop_docker 132 | SIZE=$(du -sb $CHAINDATA | awk '{print $1}') 133 | FREE_SPACE=$(df -B1 $BACKUP_LOCATION | awk 'NR==2 {print $4}') 134 | SIZE_GB=$(echo "$SIZE" | awk '{printf "%.2f", $1 / (1024^3)}') 135 | FREE_SPACE_GB=$(echo "$FREE_SPACE" | awk '{printf "%.2f", $1 / (1024^3)}') 136 | echo "" 137 | 138 | if ((SIZE < FREE_SPACE)); then 139 | sudo chmod -R 777 $CHAINDATA 140 | 141 | # Summary confirmation 142 | clear 143 | echo "===================== Compression =====================" 144 | echo "" 145 | echo "Compression provides a trade-off between backup size and backup duration:" 146 | echo " - With compression, the backup file will have a smaller size, saving storage space." 147 | echo " However, the backup process will take longer due to the compression operation." 148 | echo " - Without compression, the backup process will be faster, resulting in shorter downtime" 149 | echo " for the execution client. However, the backup file size will be larger." 150 | echo "" 151 | echo "=======================================================" 152 | 153 | read -p "Do you want to use compression? (y/N)" use_compression 154 | use_compression=${use_compression:-N} 155 | echo "" 156 | clear 157 | echo "" 158 | echo "===================== Backup Summary =====================" 159 | echo "Source Folder: $CHAINDATA ($SIZE_GB GB)" 160 | echo "Target Location: $BACKUP_LOCATION (Free Space: $FREE_SPACE_GB GB)" 161 | echo "Compression: $use_compression" 162 | echo "==========================================================" 163 | echo "" 164 | read -p "Please review the summary above. Do you want to proceed with the backup? (y/n)" confirm 165 | echo "" 166 | 167 | if [ "$confirm" != "${confirm#[Yy]}" ]; then 168 | 169 | DATE=$(date +"%Y_%m_%d_%H_%M") 170 | 171 | start_time=$(date +"%Y-%m-%d %H:%M:%S") 172 | 173 | # Backup Process 174 | echo "Started on: $start_time" 175 | 176 | if [ "$use_compression" != "${use_compression#[Yy]}" ]; then 177 | # Backup process with compression 178 | BACKUP_FILE="$BACKUP_LOCATION/chaindata_$DATE.tar.gz" 179 | (tar cfP - -C "$INSTALL_PATH/execution/geth/geth" chaindata | pigz -1 >$BACKUP_FILE) & 180 | pid=$! 181 | else 182 | # Backup process without compression 183 | BACKUP_FILE="$BACKUP_LOCATION/chaindata_$DATE.tar" 184 | (tar cfP - -C "$INSTALL_PATH/execution/geth/geth" chaindata >$BACKUP_FILE) & 185 | pid=$! 186 | fi 187 | 188 | while kill -0 $pid >/dev/null 2>&1; do 189 | sleep 1 190 | CURRENT_SIZE=$(du -sb $BACKUP_FILE | awk '{print $1}') 191 | CURRENT_SIZE_GB=$(echo "$CURRENT_SIZE" | awk '{printf "%.2f", $1 / (1024^3)}') 192 | echo -ne "Processed: $CURRENT_SIZE_GB/$SIZE_GB GB\r" 193 | done 194 | # End time 195 | end_time=$(date +"%Y-%m-%d %H:%M:%S") 196 | 197 | # Calculate duration 198 | duration=$(($(date -d "$end_time" +%s) - $(date -d "$start_time" +%s))) 199 | hours=$((duration / 3600)) 200 | minutes=$(((duration % 3600) / 60)) 201 | seconds=$((duration % 60)) 202 | 203 | sudo chown $main_user:$main_user $BACKUP_FILE 204 | sudo chmod 777 $BACKUP_FILE 205 | 206 | start_docker 207 | echo "" 208 | echo "Backup completed successfully. You can find it in $BACKUP_FILE" 209 | echo "Start time: $start_time" 210 | echo "End time: $end_time" 211 | echo "" 212 | printf "Duration: %02d:%02d:%02d\n" $hours $minutes $seconds 213 | echo "" 214 | echo "Please make sure to unmount/remove your USB-Device safely" 215 | echo "" 216 | else 217 | echo "Backup confirmation declined. Backup aborted." 218 | start_docker 219 | fi 220 | else 221 | echo "Not enough space to create the backup in the selected location." 222 | start_docker 223 | fi 224 | else 225 | echo "Backup aborted." 226 | start_docker 227 | fi 228 | } 229 | 230 | # Restore Function 231 | function restore() { 232 | while true; do 233 | info 234 | echo "" 235 | read -e -p "Please enter the full path to your backup file (e.g. /path/to/chaindata_####.tar.gz): " BACKUP_FILE 236 | echo "" 237 | if [ -f "$BACKUP_FILE" ]; then 238 | break 239 | else 240 | echo "The file does not exist. Please try again." 241 | fi 242 | done 243 | SIZE=$(du -sb $BACKUP_FILE | awk '{print $1}') 244 | SIZE_GB=$(echo "$SIZE" | awk '{printf "%.2f", $1 / (1024^3)}') 245 | DEFAULT_INSTALL_PATH="/blockchain" 246 | while true; do 247 | echo "" 248 | read -e -p "Please enter your main blockchain install path (default: /blockchain): " INSTALL_PATH 249 | echo "" 250 | INSTALL_PATH=$(readlink -m "${INSTALL_PATH:-$DEFAULT_INSTALL_PATH}") 251 | if [ -d "$INSTALL_PATH" ]; then 252 | echo "The directory exists." 253 | break 254 | else 255 | echo "The directory $INSTALL_PATH does not exist." 256 | read -p "Would you like to create it? (y/n) " yn 257 | case $yn in 258 | [Yy]* ) sudo mkdir -p "$INSTALL_PATH" && sudo chmod -R 777 "$INSTALL_PATH" 259 | echo "The directory $INSTALL_PATH has been created with permissions set to 777." 260 | break;; 261 | [Nn]* ) echo "No directory created. Please specify a valid directory." 262 | ;; 263 | * ) echo "Please answer yes (y) or no (n).";; 264 | esac 265 | fi 266 | done 267 | 268 | 269 | 270 | CHAINDATA="$INSTALL_PATH/execution/geth/geth/chaindata" 271 | # Check if there is data in the directory 272 | if [ "$(ls -A $CHAINDATA)" ]; then 273 | read -p "Directory $CHAINDATA is not empty. Do you want to delete its contents? (y/n)" delete_answer 274 | if [ "$delete_answer" != "${delete_answer#[Yy]}" ]; then 275 | stop_docker 276 | sudo rm -R "$CHAINDATA" 277 | echo "$CHAINDATA folder has been deleted." 278 | else 279 | echo "$CHAINDATA folder has not been deleted." 280 | fi 281 | fi 282 | 283 | FREE_SPACE=$(df -B1 $INSTALL_PATH | awk 'NR==2 {print $4}') 284 | if ((SIZE < FREE_SPACE)); then 285 | trap sigint_handler_restore INT 286 | stop_docker 287 | # Check if the target directory exists. If not, create it. 288 | if [ ! -d "$CHAINDATA" ]; then 289 | echo "Directory $CHAINDATA does not exist. Creating it..." 290 | sudo mkdir -p "$CHAINDATA" && sudo chmod -R 777 "$CHAINDATA" 291 | fi 292 | start_time=$(date +"%Y-%m-%d %H:%M:%S") 293 | echo "Started on: $start_time" 294 | 295 | if [[ $BACKUP_FILE == *.tar.gz ]]; then 296 | # Extraction for compressed backup file 297 | (pigz -dc "$BACKUP_FILE" | tar xfP - -C "$INSTALL_PATH/execution/geth/geth") & 298 | pid=$! 299 | else 300 | # Extraction for uncompressed backup file 301 | (tar xf "$BACKUP_FILE" -C "$INSTALL_PATH/execution/geth/geth") & 302 | pid=$! 303 | 304 | fi 305 | 306 | # Get the size of the CHAINDATA folder 307 | SIZE_CHAINDATA=$(du -sb $CHAINDATA | awk '{print $1}') 308 | SIZE_CHAINDATA_GB=$(echo "$SIZE_CHAINDATA" | awk '{printf "%.2f", $1 / (1024^3)}') 309 | 310 | # Get the size of the backup file 311 | SIZE_BACKUP_FILE=$(du -sb $BACKUP_FILE | awk '{print $1}') 312 | SIZE_BACKUP_FILE_GB=$(echo "$SIZE_BACKUP_FILE" | awk '{printf "%.2f", $1 / (1024^3)}') 313 | 314 | while kill -0 $pid >/dev/null 2>&1; do 315 | sleep 1 316 | CURRENT_SIZE=$(du -sb $CHAINDATA | awk '{print $1}') 317 | CURRENT_SIZE_GB=$(echo "$CURRENT_SIZE" | awk '{printf "%.2f", $1 / (1024^3)}') 318 | echo -ne "Processed: $CURRENT_SIZE_GB GB / $SIZE_BACKUP_FILE_GB GB\r" 319 | done 320 | 321 | start_docker 322 | end_time=$(date +"%Y-%m-%d %H:%M:%S") 323 | 324 | # Calculate duration 325 | duration=$(($(date -d "$end_time" +%s) - $(date -d "$start_time" +%s))) 326 | hours=$((duration / 3600)) 327 | minutes=$(((duration % 3600) / 60)) 328 | seconds=$((duration % 60)) 329 | 330 | echo "" 331 | echo "Restore completed successfully. The data has been restored to $CHAINDATA" 332 | echo "" 333 | echo "Start time: $start_time" 334 | echo "End time: $end_time" 335 | echo "" 336 | printf "Duration: %02d:%02d:%02d\n" $hours $minutes $seconds 337 | echo "" 338 | echo "Please make sure to unmount/remove your USB-Device safely" 339 | echo "" 340 | 341 | else 342 | echo "" 343 | echo "Restore aborted." 344 | echo "Not enough space in Target-Folder" 345 | echo "" 346 | fi 347 | } 348 | 349 | # Docker Controls 350 | function stop_docker() { 351 | if [ "$(docker ps -q -f name=execution)" ]; then 352 | echo "" 353 | read -p "Warning: The Execution-Client (go-pls) is currently running and will be stopped and resumed after the restore is complete. Do you want to continue? (y/n)" answer 354 | echo "" 355 | if [ "$answer" != "${answer#[Yy]}" ]; then 356 | echo "" 357 | echo "" 358 | docker stop -t 300 execution >/dev/null 2>&1 359 | docker container prune -f >/dev/null 2>&1 360 | fi 361 | else 362 | echo "The Execution-Client (go-pls) is currently not running." 363 | fi 364 | } 365 | 366 | 367 | function start_docker() { 368 | echo "" 369 | echo "Restarting Execution-Client..." 370 | echo "" 371 | sleep 2 372 | $INSTALL_PATH/start_execution.sh >/dev/null 2>&1 373 | if [ $? -eq 0 ]; then 374 | echo "Docker start executed successfully." 375 | else 376 | echo "Docker start execution failed." 377 | fi 378 | } 379 | 380 | # sigint Controls 381 | function sigint_handler_restore() { 382 | echo "" 383 | echo "Canceling restore..." 384 | echo "" 385 | sudo chown $main_user:$main_user "$INSTALL_PATH/execution/geth/geth/chaindata" 386 | sudo chmod -R 777 "$INSTALL_PATH/execution/geth/geth" 387 | sleep 2 388 | echo "Restarting Execution Client" 389 | echo "" 390 | sleep 2 391 | start_docker 392 | exit 0 393 | } 394 | 395 | function sigint_handler_backup() { 396 | echo "" 397 | echo "Canceling backup..." 398 | echo "" 399 | sleep 2 400 | echo "Deleting incomplete backup-file" 401 | rm $BACKUP_FILE 402 | echo "Restarting Execution Client" 403 | echo "" 404 | sleep 2 405 | start_docker 406 | exit 0 407 | } 408 | 409 | # Run the script 410 | menu 411 | 412 | # Kill the sudo session refresh process after script execution 413 | kill $SUDO_KEEP_ALIVE_PID 414 | -------------------------------------------------------------------------------- /setup_validator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # v.1.1 4 | 5 | #Icosa, Hex, Hedron, 6 | #Three shapes in symmetry dance, 7 | #Nature's art is shown. 8 | 9 | # By tdslaine aka Peter L Dipslayer TG: @dipslayer369 Twitter: @dipslayer 10 | 11 | start_dir=$(pwd) 12 | script_dir=$(dirname "$0") 13 | GREEN='\033[0;32m' 14 | RED='\033[0;31m' 15 | NC='\033[0m' 16 | 17 | source "$script_dir/functions.sh" 18 | 19 | tab_autocomplete 20 | check_and_set_network_variables 21 | 22 | echo "Setting up a validator on the $EXECUTION_NETWORK_FLAG network" 23 | 24 | sleep 2 25 | 26 | function get_user_choices() { 27 | echo "" 28 | echo "+--------------------------------------------+" 29 | echo "| Choose your Validator Client |" 30 | echo "| |" 31 | echo "| (based on your consensus/beacon Client) |" 32 | echo "+--------------------------------------------+" 33 | echo "| 1. Lighthouse |" 34 | echo "| |" 35 | echo "| 2. Prysm |" 36 | echo "+--------------------------------------------+" 37 | echo "| 0. Return or Exit |" 38 | echo "+--------------------------------------------+" 39 | echo "" 40 | read -p "Enter your choice (1, 2 or 0): " client_choice 41 | 42 | # Validate user input for client choice 43 | while [[ ! "$client_choice" =~ ^[0-2]$ ]]; do 44 | echo "Invalid input. Please enter a valid choice (1, 2 or 0): " 45 | read -p "Enter your choice (1, 2 or 0): " client_choice 46 | done 47 | 48 | if [[ "$client_choice" == "0" ]]; then 49 | echo "Exiting..." 50 | exit 0 51 | fi 52 | } 53 | 54 | # Main Setup Starts here ################################################################ 55 | 56 | # Start Validator Setup 57 | clear 58 | get_user_choices 59 | 60 | # Checking for installed/Required software 61 | common_task_software_check 62 | 63 | # Add "validator" user to system and docker-grp 64 | create_user "validator" >/dev/null 2>&1 65 | 66 | # Prompt User for Set up installation path 67 | echo "" 68 | set_install_path 69 | echo "" 70 | 71 | # Cloning staking Client into installation path 72 | clone_staking_deposit_cli "${INSTALL_PATH}" 73 | echo "" 74 | # Create PRYSM-Wallet pw.txt if First-Time Setup and User choose Prysm-Client 75 | 76 | if [[ "$client_choice" == "2" ]]; then 77 | create_subfolder "wallet" 78 | create_prysm_wallet_password 79 | sudo chmod -R 777 "${INSTALL_PATH}/wallet" 80 | sudo chown $main_user: "$INSTALL_PATH/wallet" 81 | fi 82 | 83 | sudo groupadd pls-validator > /dev/null 2>&1 84 | 85 | Staking_Cli_launch_setup 86 | 87 | sudo chmod -R 777 $INSTALL_PATH/validator_keys 88 | sudo chmod -R 777 $INSTALL_PATH/staking-deposit-cli 89 | 90 | clear 91 | 92 | # Generate Key functions 93 | 94 | ################################################### Generate New ################################################## 95 | generate_new_validator_key() { 96 | source "${INSTALL_PATH}/staking-deposit-cli/venv/bin/activate" 97 | 98 | if [[ "$client_choice" == "1" ]]; then 99 | check_and_pull_lighthouse 100 | elif [[ "$client_choice" == "2" ]]; then 101 | check_and_pull_prysm_validator 102 | fi 103 | 104 | clear 105 | 106 | warn_network 107 | 108 | clear 109 | 110 | 111 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 112 | network_interface_DOWN 113 | fi 114 | 115 | 116 | echo "" 117 | echo "Generating the validator keys via staking-cli" 118 | echo "" 119 | echo "Please follow the instructions and make sure to READ! and understand everything on screen" 120 | echo "" 121 | echo -e "${RED}Attention:${NC}" 122 | echo "" 123 | echo "The next step requires you to enter the wallet address that you would like to use for receiving" 124 | echo "validator rewards while validating and withdrawing your funds when you exit the validator pool." 125 | echo -e "This is the ${GREEN}Withdrawal- or Execution-Wallet (they are the same)${NC}" 126 | echo "" 127 | echo -e "Make sure ${RED}you have full access${NC} to this Wallet. ${RED}Once set, it cannot be changed${NC}" 128 | echo "" 129 | echo -e "You need to provide this Wallet-Adresss in the ${GREEN}proper format (checksum)${NC}." 130 | echo -e "One way to achive this, is to copy your adress from the Blockexplorer" 131 | echo "" 132 | if confirm_prompt "I have read this information and confirm that I understand the importance of using the right Withdrawal-Wallet Address."; then 133 | echo "" 134 | echo "proceeding..." 135 | sleep 2 136 | else 137 | echo "Exiting script now." 138 | network_interface_UP 139 | exit 1 140 | fi 141 | 142 | 143 | echo "" 144 | 145 | # Check if the address is a valid address, loop until it is... 146 | while true; do 147 | read -e -p "Please enter your Execution/Withdrawal-Wallet address: " withdrawal_wallet 148 | if [[ "${withdrawal_wallet}" =~ ^0x[a-fA-F0-9]{40}$ ]]; then 149 | break 150 | else 151 | echo "Invalid address format. Please enter a valid PRC20 address." 152 | fi 153 | done 154 | 155 | 156 | # Running staking-cli to Generate the new validator_keys 157 | echo "" 158 | echo "Starting staking-cli to Generate the new validator_keys" 159 | echo "" 160 | 161 | cd ${INSTALL_PATH}/staking-deposit-cli 162 | ./deposit.sh new-mnemonic \ 163 | --mnemonic_language=english \ 164 | --chain=${DEPOSIT_CLI_NETWORK} \ 165 | --folder="${INSTALL_PATH}" \ 166 | --eth1_withdrawal_address="${withdrawal_wallet}" 167 | 168 | 169 | cd "${INSTALL_PATH}" 170 | sudo chmod -R 770 "${INSTALL_PATH}/validator_keys" >/dev/null 2>&1 171 | sudo chmod -R 770 "${INSTALL_PATH}/wallet" >/dev/null 2>&1 172 | 173 | deactivate 174 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 175 | network_interface_UP 176 | fi 177 | 178 | if [[ "$client_choice" == "1" ]]; then 179 | import_lighthouse_validator 180 | elif [[ "$client_choice" == "2" ]]; then 181 | import_prysm_validator 182 | fi 183 | 184 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "keystore*.json" -exec sudo chmod 440 {} \; 185 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "deposit*.json" -exec sudo chmod 444 {} \; 186 | sudo find "$INSTALL_PATH/validator_keys" -type f -exec sudo chown $main_user:pls-validator {} \; 187 | 188 | } 189 | 190 | ################################################### Import ################################################## 191 | import_restore_validator_keys() { 192 | 193 | if [[ "$client_choice" == "1" ]]; then 194 | check_and_pull_lighthouse 195 | elif [[ "$client_choice" == "2" ]]; then 196 | check_and_pull_prysm_validator 197 | fi 198 | 199 | while true; do 200 | clear 201 | # Prompt the user to enter the path to the root directory containing the 'validator_keys' backup-folder 202 | echo -e "Enter the path to the root directory which contains the 'validator_keys' backup-folder." 203 | echo -e "For example, if your 'validator_keys' folder is located in '/home/user/my_backup/validator_keys'," 204 | echo -e "then provide the path '/home/user/my_backup'. You can use tab-autocomplete when entering the path." 205 | echo "" 206 | read -e -p "Path to backup: " backup_path 207 | 208 | # Check if the source directory exists 209 | if [ -d "${backup_path}/validator_keys" ]; then 210 | # Check if the source and destination paths are different 211 | if [ "${INSTALL_PATH}/validator_keys" != "${backup_path}/validator_keys" ]; then 212 | # Copy the validator_keys folder to the install path 213 | sudo cp -R "${backup_path}/validator_keys" "${INSTALL_PATH}" 214 | # Inform the user that the keys have been successfully copied over 215 | echo "Keys successfully copied." 216 | # Exit the loop 217 | break 218 | else 219 | # Inform the user that the source and destination paths match and no action is needed 220 | echo "Source and destination paths match. Skipping restore-copy; keys seem already in place." 221 | echo "Key import will still proceed..." 222 | # Exit the loop 223 | break 224 | fi 225 | else 226 | # Inform the user that the source directory does not exist and ask them to try again 227 | echo "Source directory does not exist. Please check the provided path and try again." 228 | fi 229 | done 230 | 231 | 232 | echo "" 233 | echo "Importing validator keys now" 234 | echo "" 235 | 236 | sudo chmod -R 770 "${INSTALL_PATH}/validator_keys" >/dev/null 2>&1 237 | sudo chmod -R 770 "${INSTALL_PATH}/wallet" >/dev/null 2>&1 238 | 239 | if [[ "$client_choice" == "1" ]]; then 240 | import_lighthouse_validator 241 | elif [[ "$client_choice" == "2" ]]; then 242 | import_prysm_validator 243 | fi 244 | 245 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "keystore*.json" -exec sudo chmod 440 {} \; 246 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "deposit*.json" -exec sudo chmod 444 {} \; 247 | sudo find "$INSTALL_PATH/validator_keys" -type f -exec sudo chown $main_user:pls-validator {} \; 248 | 249 | 250 | } 251 | 252 | ################################################### Restore ################################################## 253 | # Function to restore from SeedPhrase 254 | Restore_from_MN() { 255 | source "${INSTALL_PATH}/staking-deposit-cli/venv/bin/activate" 256 | 257 | echo "Restoring validator_keys from SeedPhrase (Mnemonic)" 258 | 259 | if [[ "$client_choice" == "1" ]]; then 260 | check_and_pull_lighthouse 261 | elif [[ "$client_choice" == "2" ]]; then 262 | check_and_pull_prysm_validator 263 | fi 264 | 265 | 266 | clear 267 | 268 | warn_network 269 | 270 | clear 271 | 272 | 273 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 274 | network_interface_DOWN 275 | fi 276 | # Check if the address is a valid address, loop until it is... 277 | while true; do 278 | read -e -p "Please enter your Execution/Withdrawal-Wallet address: " withdrawal_wallet 279 | if [[ "${withdrawal_wallet}" =~ ^0x[a-fA-F0-9]{40}$ ]]; then 280 | break 281 | else 282 | echo "Invalid address format. Please enter a valid PRC20 address." 283 | fi 284 | done 285 | 286 | 287 | echo "" 288 | echo "Now running staking-cli command to restore from your SeedPhrase (Mnemonic)" 289 | echo "" 290 | 291 | cd "${INSTALL_PATH}" 292 | sudo chmod -R 777 "${INSTALL_PATH}/validator_keys" >/dev/null 2>&1 293 | sudo chmod -R 777 "${INSTALL_PATH}/wallet" >/dev/null 2>&1 294 | 295 | cd ${INSTALL_PATH}/staking-deposit-cli/ 296 | ./deposit.sh existing-mnemonic \ 297 | --chain=${DEPOSIT_CLI_NETWORK} \ 298 | --folder="${INSTALL_PATH}" \ 299 | --eth1_withdrawal_address="${withdrawal_wallet}" 300 | 301 | deactivate 302 | if [[ "$network_off" =~ ^[Yy]$ ]]; then 303 | network_interface_UP 304 | fi 305 | 306 | if [[ "$client_choice" == "1" ]]; then 307 | import_lighthouse_validator 308 | elif [[ "$client_choice" == "2" ]]; then 309 | import_prysm_validator 310 | 311 | fi 312 | 313 | sudo chmod -R 770 "${INSTALL_PATH}/validator_keys" 314 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "keystore*.json" -exec sudo chmod 770 {} \; 315 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "deposit*.json" -exec sudo chmod 774 {} \; 316 | sudo find "$INSTALL_PATH/validator_keys" -type f -exec sudo chown $main_user:pls-validator {} \; 317 | } 318 | 319 | 320 | 321 | # Selection menu 322 | 323 | echo "-----------------------------------------" 324 | echo "| Validator Key Setup |" 325 | echo "-----------------------------------------" 326 | echo "" 327 | PS3=$'\nChoose an option (1-4): ' 328 | options=("Generate new validator_keys (fresh)" "Import/Restore validator_keys from a Folder (from Offline generation or Backup)" "Restore or Add from a Seed Phrase (Mnemonic) to current or initial setup" "Skip validator key creation") 329 | COLUMNS=1 330 | select opt in "${options[@]}" 331 | 332 | do 333 | case $REPLY in 334 | 1) 335 | generate_new_validator_key 336 | break 337 | ;; 338 | 2) 339 | import_restore_validator_keys 340 | break 341 | ;; 342 | 3) 343 | Restore_from_MN 344 | break 345 | ;; 346 | 4) 347 | echo "Skipping validator key creation. Proceeding with the next steps..." 348 | break 349 | ;; 350 | *) 351 | echo "Invalid option. Please choose option (1-4)." 352 | ;; 353 | esac 354 | done 355 | 356 | # Code from here is for fresh-install only to generate the start_validator.sh launch script. 357 | echo "" 358 | echo -e "${GREEN}Gathering data for the Validator-Client, data will be used to generate the start_validator script${NC}" 359 | echo "" 360 | 361 | echo "" 362 | get_fee_receipt_address # Set Fee-Receipt address 363 | 364 | graffiti_setup # Set Graffiti 365 | 366 | 367 | ## Defining the start_validator.sh script content, this is only done during the "first-time-setup" 368 | 369 | if [[ "$client_choice" == "1" ]]; then 370 | VALIDATOR=" 371 | sudo -u validator docker run -dt --network=host --restart=always \\ 372 | -v "${INSTALL_PATH}":/blockchain \\ 373 | --name validator \\ 374 | registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest \\ 375 | lighthouse vc \\ 376 | --network=${LIGHTHOUSE_NETWORK_FLAG} \\ 377 | --validators-dir=/blockchain/validators \\ 378 | --suggested-fee-recipient="${fee_wallet}" \\ 379 | --graffiti="${user_graffiti}" \\ 380 | --metrics \\ 381 | --beacon-nodes=http://127.0.0.1:5052 " 382 | 383 | elif [[ "$client_choice" == "2" ]]; then 384 | VALIDATOR=" 385 | sudo -u validator docker run -dt --network=host --restart=always \\ 386 | -v "${INSTALL_PATH}"/wallet:/wallet \\ 387 | -v "${INSTALL_PATH}"/validator_keys:/keys \\ 388 | --name=validator \\ 389 | registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest --${PRYSM_NETWORK_FLAG} \\ 390 | --suggested-fee-recipient="${fee_wallet}" \\ 391 | --wallet-dir=/wallet --wallet-password-file=/wallet/pw.txt \\ 392 | --graffiti "${user_graffiti}" --rpc " 393 | 394 | else 395 | echo "Error - Debugging required" 396 | 397 | fi 398 | 399 | echo "" 400 | echo "debug info:" 401 | echo -e "Creating the start_validator.sh script with the following contents:\n${VALIDATOR}" 402 | echo "" 403 | 404 | if [[ "$network_off" =~ ^[Yy]$ ]]; then # Restarting Network interface should it still be down for some reason 405 | network_interface_UP 406 | fi 407 | 408 | sudo chown :docker ${INSTALL_PATH} 409 | sudo chmod -R 770 ${INSTALL_PATH} 410 | 411 | #echo "Current directory is $(pwd)" 412 | 413 | # Writing the start_validator.sh script, this is only done during "first-setup" 414 | cat > "${INSTALL_PATH}/start_validator.sh" << EOF 415 | #!/bin/bash 416 | 417 | ${VALIDATOR} 418 | EOF 419 | 420 | get_main_user > /dev/null 2>&1 421 | 422 | echo "" 423 | echo $main_user > /dev/null 2>&1 424 | echo "" 425 | 426 | sudo chmod +x "${INSTALL_PATH}/start_validator.sh" 427 | sudo chown -R $main_user:docker ${INSTALL_PATH}/*.sh 428 | 429 | sleep 1 430 | 431 | 432 | 433 | # Setup ownership and file permissions 434 | 435 | # get main user via logname 436 | sudo groupadd pls-validator > /dev/null 2>&1 437 | sleep 1 438 | # add pls-validator groupS 439 | sudo usermod -aG pls-validator $main_user > /dev/null 2>&1 # main user to pls-validator to access folders 440 | sudo usermod -aG pls-validator validator > /dev/null 2>&1 441 | 442 | sudo chown -R validator:pls-validator "$INSTALL_PATH/validators" > /dev/null 2>&1 # set ownership to validator and pls-validator-group 443 | sudo chown -R validator:pls-validator "$INSTALL_PATH/wallet" > /dev/null 2>&1 # "" 444 | sudo chown -R validator:pls-validator "$INSTALL_PATH/validator_keys" > /dev/null 2>&1 # "" 445 | 446 | sudo chmod -R 770 "$INSTALL_PATH/validator_keys" 447 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "keystore*.json" -exec sudo chmod 770 {} \; 448 | sudo find "$INSTALL_PATH/validator_keys" -type f -name "deposit*.json" -exec sudo chmod 774 {} \; 449 | sudo find "$INSTALL_PATH/validator_keys" -type f -exec sudo chown $main_user:pls-validator {} \; 450 | 451 | sudo chmod -R 777 "$INSTALL_PATH/validator_keys" 452 | sudo chmod -R 770 "$INSTALL_PATH/wallet" > /dev/null 2>&1 453 | sudo chmod -R 770 "$INSTALL_PATH/validators" > /dev/null 2>&1 454 | 455 | cron2 456 | 457 | # Prompt the user if they want to run the scripts 458 | start_scripts_first_time 459 | 460 | ## Clearing the Bash-Histroy 461 | clear_bash_history 462 | 463 | echo "" 464 | read -e -p "$(echo -e "${GREEN}Do you want to run the Prometheus/Grafana Monitoring Setup now (y/n):${NC}")" choice 465 | 466 | while [[ ! "$choice" =~ ^(y|n)$ ]]; do 467 | read -e -p "Invalid input. Please enter 'y' or 'n': " choice 468 | done 469 | 470 | if [[ "$choice" =~ ^[Yy]$ || "$choice" == "" ]]; then 471 | # Check if the setup_monitoring.sh script exists 472 | if [[ ! -f "${start_dir}/setup_monitoring.sh" ]]; then 473 | echo "setup_monitoring.sh script not found. Aborting Prometheus/Grafana Monitoring setup." 474 | exit 1 475 | fi 476 | # Set the permission and run the setup script 477 | sudo chmod +x "${start_dir}/setup_monitoring.sh" 478 | "${start_dir}/setup_monitoring.sh" 479 | 480 | # Check if the setup script was successful 481 | if [[ $? -ne 0 ]]; then 482 | echo "Prometheus/Grafana Monitoring setup failed. Please try again or set up manually." 483 | exit 1 484 | fi 485 | 486 | exit 0 487 | else 488 | echo "Skipping Prometheus/Grafana Monitoring Setup." 489 | fi 490 | 491 | echo "" 492 | 493 | echo -e " ${RED}Note: Sync the chain fully before submitting your deposit_keys to prevent slashing; avoid using the same keys on multiple machines.${NC}" 494 | echo "" 495 | echo -e "Find more information in the repository's README." 496 | 497 | 498 | display_credits 499 | sleep 1 500 | echo "" 501 | echo "Due to changes in file-Permission it is highly recommended to reboot the system now" 502 | reboot_prompt 503 | sleep 2 504 | reboot_advice 505 | logviewer_prompt 506 | echo "" 507 | exit 0 508 | fi 509 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ### Info: Current plsmenu version: 1.5 (updated 12-13-2024) 7 | 8 | 9 | ## Installing and Running a Pulsechain Node/Validator + Prometheus/Grafana Monitoring 10 | 11 | This setup is split into three parts to provide greater flexibility for users based on their needs. 12 | 13 | The first part is the node setup, which involves setting up the core node infrastructure. This includes installing necessary packages and dependencies to run a node. (`setup_pulse_node.sh`) 14 | 15 | The second part is the validator setup, which involves configuring the node as a validator, setting up validators keys,wallets, and importing those. (`setup_validator.sh`) 16 | 17 | The third part is the monitoring setup, which involves setting up Prometheus/Grafana to keep track of the node and its performance via webinterface. (`setup_monitoring.sh`) 18 | 19 | You can run each step individually, based on your requirements, by calling the appropriate setup_###.sh script. This provides a convenient way to install and configure only the necessary components. 20 | 21 | Additionally, it's worth noting that after completing each installation step, you'll be prompted to continue with the next setup. This means that there's no need to run each script separately, as the setup process will guide you through each step in sequence. 22 | 23 | To prepare dedicated devices for offline-key generation use (`setup_offline_keygen.sh`), this will work on a linux live iso and devices which are meant to stay offline after the initial keygen setup. 24 | 25 | This streamlined approach ensures that you have a smooth and hassle-free setup experience, and can get up and running quickly. 26 | 27 | 28 | ## |#| Prerequisites 29 | 30 | - A Unix-based operating system (e.g., Ubuntu) 31 | 32 | ## |#| Installation Steps 33 | 34 | ### Single-Command 35 | 36 | Whole Setup: 37 | ```bash 38 | sudo apt update && sudo apt install git -y && git clone https://github.com/tdslaine/install_pulse_node && cd install_pulse_node && chmod +x setup_pulse_node.sh && ./setup_pulse_node.sh 39 | ``` 40 | Offline-Keygen only: 41 | ```bash 42 | sudo apt update && sudo apt install git -y && git clone https://github.com/tdslaine/install_pulse_node && cd install_pulse_node && chmod +x setup_offline_keygen.sh && ./setup_offline_keygen.sh 43 | ``` 44 | or 45 | ```bash 46 | wget https://tinyurl/valikey -O setup_offline_keygen.sh && chmod +x setup_offline_keygen.sh && ./setup_offline_keygen.sh 47 | ``` 48 | 49 | ### Manual Steps 50 | 51 | #### 1. Install Git** (if not already installed) 52 | 53 | ```bash 54 | sudo apt update && sudo apt install git -y 55 | ``` 56 | 57 | #### 2. Clone the repository 58 | 59 | ```bash 60 | git clone https://github.com/tdslaine/install_pulse_node 61 | ``` 62 | 63 | #### 3. Change to the `install_pulse_node` directory: 64 | 65 | ```bash 66 | cd install_pulse_node 67 | ``` 68 | 69 | #### 4. Give execution permissions to the `setup_pulse_node.sh` script: 70 | 71 | ```bash 72 | chmod +x setup_pulse_node.sh 73 | ``` 74 | 75 | #### 5. Run the `setup_pulse_node.sh` script: 76 | 77 | ```bash 78 | ./setup_pulse_node.sh 79 | ``` 80 | 81 | #### 6. After the initial setup 82 | 83 | :exclamation: This only applies if you didn't choose to autostart the scripts during the setup script when asked if you want to start them now! :exclamation: 84 | 85 | After completing the initial setup, you will have to run each `start_###.sh` script at least once manually. Once done, the Docker container will automatically restart in the event of a reboot or crash, without requiring manual intervention. 86 | 87 | cd into the folder you provided in the setup (default: `/blockchain`): 88 | 89 | ```bash 90 | cd /blockchain \ 91 | 92 | ./start_execution.sh \ 93 | ./start_consensus.sh \ 94 | ./start_validator.sh 95 | ``` 96 | 97 | #### 7. Make sure your docker-images are running: 98 | 99 | ```bash 100 | docker ps 101 | ``` 102 | 103 | ## |#| Managing Node/Validator 104 | 105 | There will be a couple of helper-scripts that should ease up the tasks for key-managment, viewing/following logs, stopping, restarting and updating the Docker Images gracefully, shutting down, restarting and updating the system. 106 | 107 | `plsmenu` combines most of these Tasks in one, easy to use menu. 108 | 109 | You can call `plsmenu` from anywhere in your terminal or use the "Validator Menu" Icon from Desktop if you opted to generate it during the setup. 110 | 111 | ```bash 112 | plsmenu 113 | ``` 114 | ----------------------------------------------------------------- 115 | ## |#| About validator-keys (keystore file generation): 116 | 117 | 118 | - User gets prompted to generate/import/restore keys during inital setup of the validator. 119 | - The key generation/managment can be restarted from plsmenu (plsmenu > key mgmt > add/restore keys) any time. 120 | - Keys can be added at any time into the validator. 121 | - If using the offline keygenerator users can import these keys via plsmenu > key mgmt > add/restore keys any time. 122 | 123 | Creating keystore files involves a methodical process designed for generating and managing validator keys, a quick rundown: 124 | 125 | 1. **Sequential Key Generation (Indexing)**: 126 | - **Index-Based Generation**: Keys are generated starting from index 0, with each subsequent key receiving the next sequential index. 127 | - **User-Defined Key Quantity**: The number of keys to be generated can be specified by the user. The tool creates keys sequentially from the starting index to the designated end index. 128 | 129 | 2. **Restoration of Previously Generated Keys**: 130 | - **Starting Index for Restoration**: To restore previously generated keys, users can set the starting index to the desired key-index from which restoration should begin. 131 | - **Consistent Generation Order**: The keys will always regenerate in the same sequence as initially created. 132 | 133 | 3. **Specific Key Restoration**: 134 | - **Restoring a Specific Keystore**: To restore a particular validator keystore, set the starting index to one less than the desired keystore index and generate one key. 135 | 136 | 4. **Deposit File Generation**: 137 | - **Session-Based**: The deposit file, crucial for validator registration, is generated per session. 138 | 139 | 5. **Import Process and Reuse of Keystores**: 140 | - **Skipping Imported Keystores**: Keystores already imported into a validator are skipped in subsequent import processes. 141 | - **Non-Reuse of Exited Validator Keystores**: Once a validator is exited, the associated keystore (or validator index) cannot be reused. This is crucial for maintaining the integrity and security of the network. 142 | 143 | Summary: 144 | ```bash 145 | 1. Initial Generation at Index 0 (Creating 1 Key): 146 | [Index 0] --> [Create 1 Key] --> [Keystore 1] 147 | 148 | 2. Sequential Generation from Index 0 to Index X (Creating X+1 Keys): 149 | [Index 0] --> [Create 1 Key] --> [Keystore 1] 150 | [Index 1] --> [Create 1 Key] --> [Keystore 2] 151 | [Index 2] --> [Create 1 Key] --> [Keystore 3] 152 | ... 153 | [Index X] --> [Create 1 Key] --> [Keystore X+1] 154 | 155 | Example of Creating 5 Keys Starting at Index 3: 156 | [Index 3] --> [Create 5 Keys] --> [Keystores 4 to 8] 157 | [Index 3] --> [Keystore 4] 158 | [Index 4] --> [Keystore 5] 159 | [Index 5] --> [Keystore 6] 160 | [Index 6] --> [Keystore 7] 161 | [Index 7] --> [Keystore 8] 162 | 163 | 3. Restoration of a Specific Keystore at Index X (Creating 1 Key): 164 | - To restore Keystore at Index X+1, set starting index to X 165 | [Index X] --> [Create 1 Key] --> [Restore Keystore X+1] 166 | 167 | Example for Restoring Keystore 10 (Creating 1 Key): 168 | - To restore Keystore 10, set starting index to 9 169 | [Index 9] --> [Create 1 Key] --> [Restore Keystore 10] 170 | 171 | Example of Restoring Multiple Keystores: 172 | - To restore Keystores 5 to 7, set starting index to 4 and create 3 keys 173 | [Index 4] --> [Create 3 Keys] --> [Restore Keystores 5 to 7] 174 | [Index 4] --> [Restore Keystore 5] 175 | [Index 5] --> [Restore Keystore 6] 176 | [Index 6] --> [Restore Keystore 7] 177 | 178 | ``` 179 | ----------------------------------------------------------------- 180 | 181 | ## Logging: 182 | 183 | To view the log files for the execution, beacon, and validator you can use the generated Desktop-Icons, launch them via plsmenu or call the scripts manually from within the /helper folder (default: /blockchain/helper) or use the docker logs command. 184 | 185 | There are two AIO version available. as well as the single, client specific Logs: 186 | 1. log_viewer.sh using Gnome-Terminal (Ubuntu GUI-Version) 187 | 2. tmux_logviewer.sh using tmux (terminal-based, please get to know on how to control tmux prior). 188 | 189 | 190 | #### -via plsmenu: 191 | 192 | ```bash 193 | plsmenu 194 | ``` 195 | 196 | AIO-Logs: 197 | `Logviewer > choose a type of AIO-Log` 198 | 199 | Client Specific Logs: 200 | `Logviewer > Clients Menu > desired Client > Show Logs` 201 | 202 | ----------------------------------------------------------------- 203 | 204 | #### -via Desktop Shortcut 205 | 206 | if created during setup, just double-click the UI_logs or TMUX_logs -Dekstop Icon. 207 | 208 | 209 | ----------------------------------------------------------------- 210 | 211 | #### -via script: 212 | 213 | ```bash 214 | cd /blockchain/helper 215 | ./log_viewer.sh 216 | ``` 217 | 218 | ```bash 219 | cd /blockchain/helper 220 | ./tmux_logviewer.sh 221 | ``` 222 | ----------------------------------------------------------------- 223 | 224 | #### -via single command that follows and shows the last 50 lines of the clients-log: 225 | ```bash 226 | docker logs -f --tail=50 execution 227 | docker logs -f --tail=50 beacon 228 | docker logs -f --tail=50 validator 229 | ``` 230 | 231 | 232 | 233 | ## Stopping/Restarting Containers (Do this prior to Shutdowns/Reboots) : 234 | 235 | Should you need to alter the original start_###.sh scripts or reboot/shutdown your system, you should! stop/restart the Docker Images that are currently running gracefully. 236 | Use either `plsmenu`, the stop_docker.sh/ restart_docker.sh script within the /helper folder (default: /blockchain/helper) or a manually command: 237 | 238 | #### -via plsmenu 239 | 240 | ```bash 241 | plsmenu 242 | ``` 243 | Stop All: `Clients Menu > stop all docker` 244 | 245 | 246 | Stop Single: `Clients Menu > desired Client > Stop Client` 247 | 248 | #### Note: The Shutdown and Reboot options from within plsmenu also provide a gracefull shutdown prior to perform the action. 249 | ----------------------------------------------------------------- 250 | 251 | #### -via Desktop Icon 252 | 253 | if opted to generate the Desktop icons during initial setup, you should find a `stop docker` icon on your Dekstop 254 | 255 | ----------------------------------------------------------------- 256 | 257 | #### -via script: 258 | 259 | ```bash 260 | cd /blockchain/helper 261 | ./stop_docker.sh 262 | ./restart_docker.sh 263 | ``` 264 | ----------------------------------------------------------------- 265 | 266 | #### -via aio-command: 267 | ```bash 268 | docker stop -t 300 $(docker ps -q) && docker -rm $(docker ps -q) && docker container prune -f 269 | ``` 270 | ----------------------------------------------------------------- 271 | 272 | #### -via specific command: 273 | 274 | ```bash 275 | docker stop -t 300 execution && docker -rm execution && docker container prune -f 276 | docker stop -t 180 beacon && docker -rm beacon && docker container prune -f 277 | docker stop -t 180 validator && docker -rm validator && docker container prune -f 278 | ``` 279 | 280 | ## Restarting 281 | After a Reboot the Docker-Images should launch automatically. Check the status with the command: `docker ps`. 282 | 283 | Should you need to start them manually use either `plsmenu` or the start_ scripts. 284 | 285 | #### -via plsmenu 286 | ```bash 287 | plsmenu 288 | ``` 289 | AIO: `Clients-Menu > Start all Clients` 290 | Client Specific: `Clients-Menu > desired Client > Start desired Client` 291 | 292 | ----------------------------------------------------------------- 293 | 294 | #### -via terminal 295 | 296 | ```bash 297 | cd /blockchain 298 | ./start_execution.sh 299 | ./start_consensus.sh 300 | ./start_validator.sh 301 | ``` 302 | ----------------------------------------------------------------- 303 | 304 | ## |#| Modifying flags/options 305 | 306 | If you ever find yourself in the need to change/add/remove some option-flags or alter the config you can achieve this by editing the start_###.sh script as you desire. You can use any editor available. Pay attention to end each line with a " \" (space, forward slash) except the last one. 307 | 308 | #### -via plsmenu 309 | ```bash 310 | plsmenu 311 | ``` 312 | `Clients Menu > desired Client > Edit Client config > Enter your PW > Apply Changes > Write changes to file with ctrl.+s > Exit editor with ctrl.+x > Restart client via menu` 313 | 314 | ----------------------------------------------------------------- 315 | 316 | #### -via terminal 317 | ```bash 318 | cd \blockchain 319 | sudo nano start_execution.sh 320 | ``` 321 | ----------------------------------------------------------------- 322 | ## |#| Updating plsmenu and helper files to latest version 323 | 324 | ### - initial update, if you are running my script prior from prior june 2023 and no version number is shown in plsmenu 325 | 326 | ![grafik](https://github.com/tdslaine/install_pulse_node/assets/46573429/def99e73-b16d-4939-a0cb-97c471e7e690) 327 | 328 | (Old version, no version-number is displayed) 329 | 330 | 331 | ```bash 332 | wget https://raw.githubusercontent.com/tdslaine/install_pulse_node/main/helper/update_files.sh && sudo chmod +x update_files.sh && ./update_files.sh 333 | ``` 334 | reload plsmenu 335 | 336 | 337 | 338 | 339 | ### - Updating from within plsmenu, if you are already got a version number displayed in plsmenu 340 | 341 | ![grafik](https://github.com/tdslaine/install_pulse_node/assets/46573429/ade52126-40fc-420d-95b0-3186d3d9c712) 342 | 343 | (Newer version, version-number is displa 344 | 345 | ```bash 346 | plsmenu 347 | ``` 348 | 349 | `System Menu > Update local helper files` 350 | 351 | yed) 352 | 353 | 354 | ## |#| Updating the Nodes Docker-Images 355 | 356 | To update your Docker containers/images you can use plsmenu or call the provided `update_docker.sh` script from the /helper folder (default: /blockchain/helper): 357 | 358 | #### -via plsmenu 359 | ```bash 360 | plsmenu 361 | ``` 362 | `Clients-Menu > Update all Clients` 363 | 364 | ----------------------------------------------------------------- 365 | 366 | #### -via script 367 | ```bash 368 | cd /blockchain/helper 369 | sudo ./update_docker.sh 370 | ``` 371 | 372 | The script will automatically check for updates and update the necessary containers and images. Review the output of the script to ensure that the update process was successful. 373 | 374 | ###### Note: that the update_docker script require administrative privileges to execute 375 | ----------------------------------------------------------------- 376 | 377 | ## |#| Reverting to an Older Docker Image Version 378 | 379 | In case a recent update to the Geth, Erigon, Lighthouse or Prysm Docker image causes issues, you can follow these steps to revert to a previous, stable version (e.g., v2.0.0): 380 | 381 | 1. Stop the running Docker clients: Execute the appropriate stop command or use docker stop with the container name or ID. 382 | 383 | 2. Edit the corresponding start_###.sh script: Choose the appropriate script from start_execution.sh, start_consensus.sh, or start_validator.sh. Modify the line that refers to the Docker image, changing the image version from :latest to the desired older version. For this example in start_execution.sh: 384 | 385 | Change this line: 386 | ```bash 387 | registry.gitlab.com/pulsechaincom/go-pulse:latest 388 | ``` 389 | To: 390 | ```bash 391 | registry.gitlab.com/pulsechaincom/go-pulse:v2.0.0 392 | ``` 393 | 394 | 3. Save the changes and restart the appropriate client: Execute the modified start_###.sh script to restart the client with the older Docker image version. 395 | 396 | By following these steps, you can revert to a previous, stable version of the Docker image and continue working without disruption. Be sure to communicate any changes made to the team to maintain consistency across your systems. 397 | 398 | Note: you can find the version history for each docker-image on the gitlab https://gitlab.com/pulsechaincom from the pulsedevs. 399 | For example for geth it would be: https://gitlab.com/pulsechaincom/go-pulse/container_registry/2121084 - you have to click next until you are at the last page. 400 | ###### howto get there: On the Page, choose your desired client > on left side navigation Panel click "Packages and registries" > then click "Packages and registries" 401 | 402 | 403 | ## |#| Prometheus/Grafana Monitoring: 404 | 405 | ### Setup 406 | 407 | :exclamation: If you opted not to run the monitoring setup during the validator setup, follow these steps: :exclamation: 408 | 409 | Make the `setup_monitoring.sh` script executable: 410 | ```bash 411 | sudo chmod +x setup_monitoring.sh 412 | ``` 413 | Run the `setup_monitoring.sh` script to start the Prometheus and Grafana Docker containers: 414 | ```bash 415 | ./setup_monitoring.sh 416 | ``` 417 | ### Adding Dashboards 418 | 419 | After the containers have started, open Grafana in your browser at: 420 | 421 | ```bash 422 | http://127.0.0.1:3000 423 | ``` 424 | Log in to Grafana with the following credentials: 425 | - User: `admin` 426 | - Password: `admin` 427 | To add dashboards, navigate to: 428 | ```bash 429 | http://127.0.0.1:3000/dashboard/import 430 | ``` 431 | Import the JSON files from your setup target directory (default: `/blockchain/Dashboards` - these were downloaded during the setup process). 432 | 433 | That's it! Prometheus and Grafana should now be up and running on your machine, allowing you to import more dashboards tailored to your needs. 434 | 435 | ### Allow Access from within your local Network 436 | :exclamation: If you opted not to allow access from within your local-network to Grafana during the monitoring setup, follow these steps: :exclamation: 437 | 438 | 1. Find current local IP-Range: 439 | To find your own IP address range, you can use the `hostname -I` command. Open a terminal and enter the following command: 440 | 441 | ```bash 442 | sudo hostname -I | awk '{print $1}' 443 | ``` 444 | This will display your IP address 445 | 446 | 2. Set UFW Rule: 447 | To allow access to the Grafana dashboard within your local subnet, run the ufw command with the appropriate IP range. For example, if your local IP address is 192.168.0.10, you can allow the entire IP range of 192.168.0.0-192.168.0.254 to access port 3000 by using the following command: 448 | 449 | ```bash 450 | sudo ufw allow from 192.168.0.0/24 to any port 3000 451 | ``` 452 | Once done, you can reload your firewall and should be able to access your grafana interface via http://IP_FROM_NODE:3000 453 | 454 | ```bash 455 | sudo ufw reload 456 | ``` 457 | 458 | 459 | ### Resources: 460 | 461 | Official Homepage: https://pulsechain.com/ 462 | 463 | Official Gitlab: https://gitlab.com/pulsechaincom 464 | 465 | Validator-Launchpad: https://launchpad.pulsechain.com/en/overview 466 | 467 | Checkpoint: https://checkpoint.pulsechain.com/ 468 | 469 | Pulsedev Telegram: https://t.me/PulseDEV 470 | 471 | -------------------------------------------------------------------------------------------- 472 | 473 | ssh: https://www.digitalocean.com/community/tutorials/how-to-harden-openssh-on-ubuntu-20-04 474 | 475 | ssh-tunneling: https://linuxize.com/post/how-to-setup-ssh-tunneling/ 476 | 477 | ufw: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-20-04 478 | 479 | tmux: https://tmuxcheatsheet.com/ 480 | -------------------------------------------------------------------------------- /helper/menu.sh: -------------------------------------------------------------------------------- 1 | VERSION="1.5" 2 | 3 | 4 | trap cleanup SIGINT 5 | 6 | function cleanup() { 7 | clear 8 | echo "Exiting..." 9 | exit 10 | } 11 | 12 | script_launch() { 13 | local script_name=$1 14 | local script_path="${helper_scripts_path}/${script_name}" 15 | 16 | if [[ -x ${script_path} ]]; then 17 | ${script_path} 18 | else 19 | echo "Error: ${script_path} not found or not executable." 20 | exit 1 21 | fi 22 | } 23 | helper_scripts_path="/blockchain/helper" 24 | CUSTOM_PATH="/blockchain" 25 | 26 | script_launch() { 27 | echo "Launching script: ${CUSTOM_PATH}/helper/$1" 28 | ${CUSTOM_PATH}/helper/$1 29 | } 30 | 31 | main_menu() { 32 | while true; do 33 | main_opt=$(dialog --stdout --title "Main Menu $VERSION" --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 \ 34 | "Logviewer" "Start different Logviewer" \ 35 | "Clients Menu" "Execution, Beacon and Validator Clients" \ 36 | "Info and KeyManagment" "Tools for Key Management and Node/Validator Information" \ 37 | "System" "Update, Reboot, shutdown, Backup & Restore" \ 38 | "-" ""\ 39 | "exit" "Exit the program") 40 | 41 | case $? in 42 | 0) 43 | case $main_opt in 44 | "Logviewer") 45 | logviewer_submenu 46 | ;; 47 | "Clients Menu") 48 | client_actions_submenu 49 | ;; 50 | "Info and KeyManagment") 51 | validator_setup_submenu 52 | ;; 53 | "System") 54 | system_submenu 55 | ;; 56 | "-") 57 | ;; 58 | "exit") 59 | clear 60 | break 61 | ;; 62 | esac 63 | ;; 64 | 1) 65 | break 66 | ;; 67 | esac 68 | done 69 | } 70 | 71 | logviewer_submenu() { 72 | while true; do 73 | lv_opt=$(dialog --stdout --title "Logviewer Menu $VERSION" --stdout --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 \ 74 | "Tabbed-Terminal Logs" "Multiple Tabs" \ 75 | "Tmux-Style Logs" "Single Window" \ 76 | "-" ""\ 77 | "back" "Back to main menu") 78 | 79 | case $? in 80 | 0) 81 | case $lv_opt in 82 | "Tabbed-Terminal Logs") 83 | clear && script_launch "log_viewer.sh" 84 | ;; 85 | "Tmux-Style Logs") 86 | clear && script_launch "tmux_logviewer.sh" 87 | ;; 88 | "-") 89 | ;; 90 | "back") 91 | break 92 | ;; 93 | esac 94 | ;; 95 | 1) 96 | break 97 | ;; 98 | esac 99 | done 100 | } 101 | 102 | client_actions_submenu() { 103 | while true; do 104 | ca_opt=$(dialog --stdout --title "Client Menu $VERSION" --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 \ 105 | "Execution-Client Menu" ""\ 106 | "Beacon-Client Menu" ""\ 107 | "Validator-Client Menu" ""\ 108 | "-" ""\ 109 | "Start all Clients" ""\ 110 | "Stop all Clients" ""\ 111 | "Restart all Clients" ""\ 112 | "Update all Clients" ""\ 113 | "-" ""\ 114 | "back" "Back to main menu") 115 | 116 | case $? in 117 | 0) 118 | case $ca_opt in 119 | "Execution-Client Menu") 120 | execution_submenu 121 | ;; 122 | "Beacon-Client Menu") 123 | beacon_submenu 124 | ;; 125 | "Validator-Client Menu") 126 | validator_submenu 127 | ;; 128 | "-") 129 | ;; 130 | "Start all Clients") 131 | clear 132 | ${CUSTOM_PATH}/start_execution.sh 133 | ${CUSTOM_PATH}/start_consensus.sh 134 | ${CUSTOM_PATH}/start_validator.sh 135 | ;; 136 | "Stop all Clients") 137 | clear && script_launch "stop_docker.sh" 138 | ;; 139 | "Restart all Clients") 140 | clear && script_launch "stop_docker.sh" 141 | ${CUSTOM_PATH}/start_execution.sh 142 | ${CUSTOM_PATH}/start_consensus.sh 143 | ${CUSTOM_PATH}/start_validator.sh 144 | ;; 145 | "Update all Clients") 146 | clear && script_launch "update_docker.sh" 147 | ${CUSTOM_PATH}/start_execution.sh 148 | ${CUSTOM_PATH}/start_consensus.sh 149 | ${CUSTOM_PATH}/start_validator.sh 150 | ;; 151 | "back") 152 | break 153 | ;; 154 | esac 155 | ;; 156 | 1) 157 | break 158 | ;; 159 | esac 160 | done 161 | } 162 | 163 | execution_submenu() { 164 | while true; do 165 | exe_opt=$(dialog --stdout --title "Execution-Client Menu $VERSION" --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 \ 166 | "Start Execution-Client" "" \ 167 | "Stop Execution-Client" "" \ 168 | "Restart Execution-Client" "" \ 169 | "-" ""\ 170 | "Edit Execution-Client Config" "" \ 171 | "Show Logs" "" \ 172 | "Update Execution-Client" "" \ 173 | "-" ""\ 174 | "back" "Back to Client Actions Menu") 175 | 176 | case $? in 177 | 0) 178 | case $exe_opt in 179 | "Start Execution-Client") 180 | clear && ${CUSTOM_PATH}/start_execution.sh 181 | ;; 182 | "Stop Execution-Client") 183 | clear && sudo docker stop -t 300 execution 184 | sleep 1 185 | sudo docker container prune -f 186 | ;; 187 | "Restart Execution-Client") 188 | clear && sudo docker stop -t 300 execution 189 | sleep 1 190 | sudo docker container prune -f 191 | clear && ${CUSTOM_PATH}/start_execution.sh 192 | ;; 193 | "Edit Execution-Client Config") 194 | clear && sudo nano "${CUSTOM_PATH}/start_execution.sh" 195 | ;; 196 | "Show Logs") 197 | clear && sudo docker logs -f execution 198 | ;; 199 | "Update Execution-Client") 200 | clear && docker stop -t 300 execution 201 | docker container prune -f && docker image prune -f 202 | docker rmi registry.gitlab.com/pulsechaincom/go-pulse > /dev/null 2>&1 203 | docker rmi registry.gitlab.com/pulsechaincom/go-erigon > /dev/null 2>&1 204 | ${CUSTOM_PATH}/start_execution.sh 205 | ;; 206 | "-") 207 | ;; 208 | "back") 209 | break 210 | ;; 211 | esac 212 | ;; 213 | 1) 214 | break 215 | ;; 216 | esac 217 | done 218 | } 219 | 220 | beacon_submenu() { 221 | while true; do 222 | bcn_opt=$(dialog --stdout --title "Beacon-Client Menu $VERSION" --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 \ 223 | "Start Beacon-Client" "" \ 224 | "Stop Beacon-Client" "" \ 225 | "Restart Beacon-Client" "" \ 226 | "-" ""\ 227 | "Edit Beacon-Client Config" "" \ 228 | "Show Logs" "" \ 229 | "Update Beacon-Client" "" \ 230 | "-" ""\ 231 | "back" "Back to Client Actions Menu") 232 | 233 | case $? in 234 | 0) 235 | case $bcn_opt in 236 | "Start Beacon-Client") 237 | clear && ${CUSTOM_PATH}/start_consensus.sh 238 | ;; 239 | "Stop Beacon-Client") 240 | clear && sudo docker stop -t 180 beacon 241 | sleep 1 242 | sudo docker container prune -f 243 | ;; 244 | "Restart Beacon-Client") 245 | clear && sudo docker stop -t 180 beacon 246 | sleep 1 247 | sudo docker container prune -f 248 | ${CUSTOM_PATH}/start_consensus.sh 249 | ;; 250 | "Edit Beacon-Client Config") 251 | clear && sudo nano "${CUSTOM_PATH}/start_consensus.sh" 252 | ;; 253 | "Show Logs") 254 | clear && sudo docker logs -f beacon 255 | ;; 256 | "Update Beacon-Client") 257 | clear && docker stop -t 180 beacon 258 | docker container prune -f && docker image prune -f 259 | docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain > /dev/null 2>&1 260 | docker rmi registry.gitlab.com/pulsechaincom/lighthouse-pulse > /dev/null 2>&1 261 | ${CUSTOM_PATH}/start_consensus.sh 262 | ;; 263 | "-") 264 | ;; 265 | "back") 266 | break 267 | ;; 268 | esac 269 | ;; 270 | 1) 271 | break 272 | ;; 273 | esac 274 | done 275 | } 276 | 277 | validator_submenu() { 278 | while true; do 279 | val_opt=$(dialog --stdout --title "Validator-Client Menu $VERSION" --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 \ 280 | "Start Validator-Client" "" \ 281 | "Stop Validator-Client" "" \ 282 | "Restart Validator-Client" "" \ 283 | "-" ""\ 284 | "Edit Validator-Client Config" "" \ 285 | "Show Logs" ""\ 286 | "Update Validator-Client" "" \ 287 | "-" "" \ 288 | "back" "Back to Client Actions Menu") 289 | 290 | case $? in 291 | 0) 292 | case $val_opt in 293 | "Start Validator-Client") 294 | clear && ${CUSTOM_PATH}/start_validator.sh 295 | ;; 296 | "Stop Validator-Client")${CUSTOM_PATH}/ 297 | clear && sudo docker stop -t 180 validator 298 | sleep 1 299 | sudo docker container prune -f 300 | ;; 301 | "Restart Validator-Client") 302 | clear && sudo docker stop -t 180 validator 303 | sleep 1 304 | sudo docker container prune -f 305 | clear && ${CUSTOM_PATH}/start_validator.sh 306 | ;; 307 | "Edit Validator-Client Config") 308 | clear && sudo nano "${CUSTOM_PATH}/start_validator.sh" 309 | ;; 310 | "Show Logs") 311 | clear && sudo docker logs -f validator 312 | ;; 313 | "Update Validator-Client") 314 | clear && docker stop -t 180 validator 315 | docker container prune -f && docker image prune -f 316 | docker rmi registry.gitlab.com/pulsechaincom/prysm-pulse/validator > /dev/null 2>&1 317 | docker rmi registry.gitlab.com/pulsechaincom/lighthouse-pulse > /dev/null 2>&1 318 | ${CUSTOM_PATH}/start_validator.sh 319 | ;; 320 | "-") 321 | ;; 322 | "back") 323 | break 324 | ;; 325 | esac 326 | ;; 327 | 1) 328 | break 329 | ;; 330 | esac 331 | done 332 | } 333 | 334 | 335 | validator_setup_submenu() { 336 | while true; do 337 | options=("Key Management" "Generate, Add, Import or Restore Validator-Keys" \ 338 | "-" "" \ 339 | "Convert BLS-Keys" "00-BLS to 01-Execution Wallet conversion" \ 340 | "Exit your Validator(s)" "Initiate the Exit of your Validator(s)" \ 341 | "-" "" \ 342 | "Client Info" "Prints currently used client version" \ 343 | "-" "" \ 344 | "GoPLS - BlockMonitor" "Compare local Block# with scan.puslechain.com" \ 345 | "GoPLS - Database Prunning" "Prune your local DB to freeup space" \ 346 | "-" "" \ 347 | "Prysm - List Accounts" "List all Accounts from the Validator DB" \ 348 | "Prysm - Delete Validator" "Delete/Remove Accounts from Validator" \ 349 | "Prysm - Add p2p-host-ip" "Fix for v.2.2.4" \ 350 | "Prysm - Temp. fix CPU-Bug" "Temporarly revert back to v2.2.2" \ 351 | "-" "" \ 352 | "Validator Info per indice" "Backup, should beacon.pulsechain.com be down"\ 353 | "Check for Sync Committee" "Checks if local Valis are in the Sync Committee"\ 354 | "-" "" 355 | "ReRun Initial Setup" "" \ 356 | "-" ""\ 357 | "back" "Back to main menu; Return to the main menu.") 358 | vs_opt=$(dialog --stdout --title "Info and KeyManagment $VERSION" --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 "${options[@]}") 359 | case $? in 360 | 0) 361 | case $vs_opt in 362 | "Key Management") 363 | clear && script_launch "key_mgmt.sh" 364 | ;; 365 | "-") 366 | ;; 367 | "Convert BLS-Keys") 368 | clear && script_launch "bls_to_execution.sh" 369 | ;; 370 | "Exit your Validator(s)") 371 | clear && script_launch "exit_validator.sh" 372 | ;; 373 | "-") 374 | ;; 375 | "Client Info") 376 | clear && script_launch "show_version.sh" 377 | ;; 378 | "-") 379 | ;; 380 | "GoPLS - BlockMonitor") 381 | clear && script_launch "compare_blocks.sh" 382 | ;; 383 | "GoPLS - Database Prunning") 384 | tmux new-session -s prune $CUSTOM_PATH/helper/gopls_prune.sh 385 | ;; 386 | "-") 387 | ;; 388 | "Prysm - List Accounts") 389 | clear && script_launch "prysm_read_accounts.sh" 390 | ;; 391 | "Prysm - Delete Validator") 392 | clear && script_launch "prysm_delete_validator.sh" 393 | ;; 394 | "Prysm - Add p2p-host-ip") 395 | clear && script_launch "prysm_fix_host_ip.sh" 396 | ;; 397 | "Prysm - Temp. fix CPU-Bug") 398 | clear && script_launch "prysm_fix.sh" 399 | ;; 400 | "-") 401 | ;; 402 | "Validator Info per indice") 403 | clear && script_launch "status_batch.sh" 404 | ;; 405 | "Check for Sync Committee") 406 | clear && script_launch "check_sync.sh" 407 | ;; 408 | "-") 409 | ;; 410 | "ReRun Initial Setup") 411 | clear && script_launch "setup_validator.sh" 412 | ;; 413 | "back") 414 | break 415 | ;; 416 | esac 417 | ;; 418 | 1) 419 | break 420 | ;; 421 | esac 422 | done 423 | } 424 | 425 | 426 | system_submenu() { 427 | while true; do 428 | sys_opt=$(dialog --stdout --title "System Menu $VERSION" --backtitle "created by DipSlayer" --menu "Choose an option:" 0 0 0 \ 429 | "Update Local Helper-Files" "Get latest additions/changes for plsmenu" \ 430 | "Add Graceful-Shutdown to System" "for system shutdown/reboot" \ 431 | "-" "" \ 432 | "Update & Reboot System" "" \ 433 | "Reboot System" "" \ 434 | "Shutdown System" "" \ 435 | "-" "" \ 436 | "Backup and Restore" "Chaindata for go-pulse" \ 437 | "-" "" \ 438 | "back" "Back to main menu") 439 | 440 | case $? in 441 | 0) 442 | case $sys_opt in 443 | "Update Local Helper-Files") 444 | clear && script_launch "update_files.sh" 445 | ;; 446 | "Add Graceful-Shutdown to System") 447 | clear && script_launch "grace.sh" 448 | ;; 449 | "-") 450 | ;; 451 | "Update & Reboot System") 452 | clear 453 | echo "Stopping running docker container..." 454 | script_launch "stop_docker.sh" 455 | sleep 3 456 | clear 457 | echo "Getting System updates..." 458 | sudo apt update && sudo apt upgrade -y && sudo apt dist-upgrade -y && sudo apt autoremove -y 459 | read -p "Update done, reboot now? Press enter to continue or Ctrl+C to cancel." 460 | sleep 5 461 | sudo reboot now 462 | ;; 463 | "Reboot System") 464 | echo "Stopping running docker container..." 465 | script_launch "stop_docker.sh" 466 | sleep 3 467 | read -p "Reboot now? Press enter to continue or Ctrl+C to cancel." 468 | sudo reboot now 469 | ;; 470 | "Shutdown System") 471 | echo "Stopping running docker container..." 472 | script_launch "stop_docker.sh" 473 | sleep 3 474 | read -p "Shutdown now? Press enter to continue or Ctrl+C to cancel." 475 | sudo shutdown now 476 | ;; 477 | 478 | "-") 479 | ;; 480 | "Backup and Restore") 481 | if tmux has-session -t bandr 2>/dev/null; then 482 | # If the session exists, attach to it 483 | tmux attach-session -t bandr 484 | else 485 | # If the session does not exist, create and attach to it 486 | tmux new-session -d -s bandr $CUSTOM_PATH/helper/backup_restore.sh 487 | tmux attach-session -t bandr 488 | fi 489 | ;; 490 | "-") 491 | ;; 492 | "back") 493 | break 494 | ;; 495 | esac 496 | ;; 497 | 1) 498 | break 499 | ;; 500 | esac 501 | done 502 | } 503 | 504 | main_menu 505 | -------------------------------------------------------------------------------- /setup_pulse_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # v.1.1 4 | 5 | #Icosa, Hex, Hedron, 6 | #Three shapes in symmetry dance, 7 | #Nature's art is shown. 8 | 9 | # By tdslaine aka Peter L Dipslayer TG: @dipslayer369 Twitter: @dipslayer 10 | 11 | 12 | GREEN='\033[0;32m' 13 | RED='\033[0;31m' 14 | NC='\033[0m' # No Color 15 | 16 | start_dir=$(pwd) 17 | script_dir=$(dirname "$0") 18 | 19 | source "$script_dir/functions.sh" 20 | 21 | clear 22 | echo " Pulse Node/Validator/Monitoring Setup by Dipslayer" 23 | echo " 24 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 25 | ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 26 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ 27 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 28 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 29 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 30 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 31 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 32 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 33 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 34 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓ 35 | ▓▓ ▓▓▓ ▓▓▓ ▓▓ 36 | ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 37 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 38 | ░▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▓▓▓▓▓ ▓▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 39 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 40 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 41 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 42 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 43 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 44 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 45 | ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 46 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 47 | " 48 | 49 | 50 | echo "Please press Enter to continue..." 51 | read -p "" 52 | clear 53 | echo -e "\033[1;33m" 54 | echo "┌─────────────────────────────────────────────────────────┐" 55 | echo "│ DISCLAIMER! Please read the following carefully! │" 56 | echo "├─────────────────────────────────────────────────────────┤" 57 | echo "│ This script automates the installation and setup │" 58 | echo "│ process for a PulseChain Node/Validator. │" 59 | echo "│ │" 60 | echo "│ By using this script, you acknowledge that you |" 61 | echo "| understand the potential risks involved and accept │" 62 | echo "│ full responsibility for the security and custody │" 63 | echo "│ of your own assets. │" 64 | echo "│ │" 65 | echo "│ It is strongly recommended that you review the script │" 66 | echo "│ and understand its workings before proceeding. │" 67 | echo "└─────────────────────────────────────────────────────────┘" 68 | echo -e "\033[0m" 69 | 70 | read -p "Do you wish to continue? (y/n): " CONFIRM 71 | if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then 72 | echo "Aborting." 73 | exit 1 74 | fi 75 | clear 76 | echo -e "\033[1;33m" 77 | echo -e "+============================================+" 78 | echo -e "| ☆ Shoutouts ☆ |" 79 | echo -e "+============================================+" 80 | echo -e "| Sincere thanks to @rainbowtopgun for his |" 81 | echo -e "| invaluable feedback & steadfast support |" 82 | echo -e "| during the development of these scripts. |" 83 | echo -e "| |" 84 | echo -e "| Special thanks to raskitoma for forking |" 85 | echo -e "| the Yoldark_ETH_staking_dashboard. GitHub: |" 86 | echo -e "| https://github.com/raskitoma/pulse- |" 87 | echo -e "| staking-dashboard |" 88 | echo -e "| |" 89 | echo -e "| Gratitude to the Pulse-dev Telegram for |" 90 | echo -e "| their valuable info & collective wisdom. |" 91 | echo -e "| |" 92 | echo -e "| Big thanks to all who contributed with |" 93 | echo -e "| constructive feedback to improve my work! |" 94 | echo -e "+--------------------------------------------+" 95 | echo -e "\033[0m" 96 | 97 | press_enter_to_continue 98 | clear 99 | echo "+=================+" 100 | echo "| Choose Network: |" 101 | echo "+=================+" 102 | echo "| 1) Mainnet |" 103 | echo "| |" 104 | echo "| 2) Testnet |" 105 | echo "+-----------------+" 106 | echo "" 107 | read -p "Enter your Network choice (1 or 2): " -r choice 108 | 109 | case $choice in 110 | 1) 111 | set_network_variables "mainnet" 112 | ;; 113 | 2) 114 | set_network_variables "testnet" 115 | ;; 116 | *) 117 | echo "Invalid choice. Exiting." 118 | exit 1 119 | ;; 120 | esac 121 | 122 | 123 | 124 | #enabling ntp for timesyncronization 125 | clear 126 | echo "" 127 | echo "We are going to setup the timezone first, it is important to be synced in time for the Chain to work correctly" 128 | sleep 2 129 | echo "enabling ntp for timesync" 130 | sudo timedatectl set-ntp true 131 | echo "" 132 | echo "enabled ntp timesync" 133 | echo "" 134 | echo -e "${RED}Please choose your CORRECT timezone at the following screen${NC}" 135 | echo "" 136 | echo "Press Enter to continue..." 137 | read -p "" 138 | sudo dpkg-reconfigure tzdata 139 | echo "timezone set" 140 | sleep 1 141 | echo "" 142 | clear 143 | echo "+=============================================================+" 144 | echo "| Please choose a Execution-Client: |" 145 | echo "+=============================================================+" 146 | echo "| 1) Geth (full node, faster sync time.) |" 147 | echo "| Recommended for normal usage, stores all transactions |" 148 | echo "| and the most recent states |" 149 | echo "+-------------------------------------------------------------+" 150 | echo "| 2) Erigon (archive node, longer sync time.) |" 151 | echo "| Recommended for developers and advanced users, |" 152 | echo "| stores the entire history of the Ethereum blockchain, |" 153 | echo "| including all historical states |" 154 | echo "+-------------------------------------------------------------+" 155 | echo "| 3) Erigon (pruned to keep last 2000 blocks) |" 156 | echo "| WARNING !: Still testing if this is beneficial over geth |" 157 | echo "| so use with caution. No guarantee this will work. |" 158 | echo "| It will only keep the last 2000 blocks |" 159 | echo "+-------------------------------------------------------------+" 160 | echo "" 161 | while true; do 162 | read -e -p "Enter your Client choice (1, 2, or 3): " ETH_CLIENT_CHOICE 163 | case $ETH_CLIENT_CHOICE in 164 | 1) 165 | ETH_CLIENT="geth" 166 | break 167 | ;; 168 | 2) 169 | ETH_CLIENT="erigon" 170 | break 171 | ;; 172 | 3) 173 | ETH_CLIENT="erigon" 174 | break 175 | ;; 176 | *) 177 | echo "Invalid choice. Please enter a valid choice (1, 2, or 3)." 178 | ;; 179 | esac 180 | done 181 | 182 | 183 | while true; do 184 | echo "" 185 | echo "" 186 | echo -e "+===================================+" 187 | echo -e "| Choose your Consensus client: |" 188 | echo -e "+===================================+" 189 | echo -e "| 1) Lighthouse |" 190 | echo -e "| 2) Prysm |" 191 | echo -e "+-----------------------------------+" 192 | echo "" 193 | read -p "Enter your Client choice (1 or 2): " CONSENSUS_CLIENT_CHOICE 194 | 195 | case $CONSENSUS_CLIENT_CHOICE in 196 | 1) 197 | CONSENSUS_CLIENT="lighthouse" 198 | break 199 | ;; 200 | 2) 201 | CONSENSUS_CLIENT="prysm" 202 | break 203 | ;; 204 | *) 205 | echo "Invalid choice. Please enter a valid choice (1 or 2)." 206 | ;; 207 | esac 208 | done 209 | 210 | # Enable tab autocompletion for the read command if line editing is enabled 211 | if [ -n "$BASH_VERSION" ] && [ -n "$PS1" ] && [ -t 0 ]; then 212 | bind '"\t":menu-complete' 213 | fi 214 | clear 215 | 216 | # Get custom path for the blockchain folder 217 | echo "" 218 | echo -e "+===============================================================+" 219 | echo -e "| Node/Clients and all required DataFolders/files will be |" 220 | echo -e "| installed under the specified path. It includes databases, |" 221 | echo -e "| keystore, and various startup/helper scripts. |" 222 | echo -e "+===============================================================+" 223 | echo "" 224 | read -e -p 'Enter target path (Press Enter for default: /blockchain): ' CUSTOM_PATH 225 | echo "" 226 | 227 | # Set the default value for custom path if the user enters nothing 228 | if [ -z "$CUSTOM_PATH" ]; then 229 | CUSTOM_PATH="/blockchain" 230 | fi 231 | 232 | # Docker run commands for Ethereum clients 233 | GETH_CMD="sudo -u geth docker run -dt --restart=always \\ 234 | --network=host \\ 235 | --name execution \\ 236 | -v ${CUSTOM_PATH}:/blockchain \\ 237 | registry.gitlab.com/pulsechaincom/go-pulse:latest \\ 238 | --${EXECUTION_NETWORK_FLAG} \\ 239 | --authrpc.jwtsecret=/blockchain/jwt.hex \\ 240 | --datadir=/blockchain/execution/geth \\ 241 | --http \\ 242 | --ws \\ 243 | --state.scheme=path \\ 244 | --gpo.ignoreprice 1 \\ 245 | --metrics \\ 246 | --pprof \\ 247 | --ws.api web3,eth,txpool,net,engine \\ 248 | --http.api web3,eth,txpool,net,engine,admin,debug " 249 | 250 | ERIGON_CMD="sudo -u erigon docker run -dt --restart=always \\ 251 | --network=host \\ 252 | --name execution \\ 253 | -v ${CUSTOM_PATH}:/blockchain \\ 254 | registry.gitlab.com/pulsechaincom/erigon-pulse:latest \\ 255 | --chain=${EXECUTION_NETWORK_FLAG} \\ 256 | --authrpc.jwtsecret=/blockchain/jwt.hex \\ 257 | --datadir=/blockchain/execution/erigon \\ 258 | --http \\ 259 | --http.api="eth,erigon,web3,net,debug,trace,txpool" \\ 260 | --metrics \\ 261 | --pprof \\ 262 | --snpashots=false " 263 | 264 | ERIGON_CMD2="sudo -u erigon docker run -dt --restart=always \\ 265 | --network=host \\ 266 | --name execution \\ 267 | -v ${CUSTOM_PATH}:/blockchain \\ 268 | registry.gitlab.com/pulsechaincom/erigon-pulse:latest \\ 269 | --chain=${EXECUTION_NETWORK_FLAG} \\ 270 | --authrpc.jwtsecret=/blockchain/jwt.hex \\ 271 | --datadir=/blockchain/execution/erigon \\ 272 | --http \\ 273 | --http.api="eth,erigon,web3,net,debug,trace,txpool" \\ 274 | --metrics \\ 275 | --pprof \\ 276 | --snpashots=false \\ 277 | --prune.h.older=2000 \\ 278 | --prune.t.older=2000 \\ 279 | --prune.c.older=2000 \\ 280 | --prune=r " 281 | 282 | # Docker run commands for Consensus clients 283 | PRYSM_CMD="# Retrieve the current IP address 284 | #IP=\$(curl -s ipinfo.io/ip) 285 | #if [ -z \"\$IP\" ]; then 286 | # echo \"Failed to retrieve IP address. Exiting...\" 287 | # echo "" 288 | #fi 289 | 290 | sudo -u prysm docker run -dt --restart=always \\ 291 | --network=host \\ 292 | --name beacon \\ 293 | -v ${CUSTOM_PATH}:/blockchain \\ 294 | registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain:latest \\ 295 | --${PRYSM_NETWORK_FLAG} \\ 296 | --jwt-secret=/blockchain/jwt.hex \\ 297 | --datadir=/blockchain/consensus/prysm \\ 298 | --checkpoint-sync-url=${CHECKPOINT} \\ 299 | --min-sync-peers 1 \\ 300 | --genesis-beacon-api-url=${CHECKPOINT} \\ 301 | #--p2p-host-ip \$IP 302 | " 303 | 304 | LIGHTHOUSE_CMD="sudo -u lighthouse docker run -dt --restart=always \\ 305 | --network=host \\ 306 | --name beacon \\ 307 | -v ${CUSTOM_PATH}:/blockchain \\ 308 | registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest \\ 309 | lighthouse bn \\ 310 | --network=${LIGHTHOUSE_NETWORK_FLAG} \\ 311 | --execution-jwt=/blockchain/jwt.hex \\ 312 | --datadir=/blockchain/consensus/lighthouse \\ 313 | --execution-endpoint=http://localhost:8551 \\ 314 | --checkpoint-sync-url=${CHECKPOINT} \\ 315 | --staking \\ 316 | --metrics \\ 317 | --validator-monitor-auto \\ 318 | --http " 319 | 320 | # Use the variables in both single and separate script modes 321 | clear 322 | # check for any snap Version of docker installed and remove it (because it enables images to be mounted writable only in home folders) 323 | 324 | if snap list | grep -q '^docker '; then 325 | echo "Docker snap package found. Removing..." 326 | sudo snap remove docker 327 | else 328 | echo "No Docker snap package found." 329 | fi 330 | 331 | # Add the deadsnakes PPA repository to install the latest Python version 332 | sudo apt-get update -y 333 | sudo apt-get install -y software-properties-common cron 334 | echo -e "${GREEN}Adding deadsnakes PPA to get the latest Python Version${NC}" 335 | sudo add-apt-repository ppa:deadsnakes/ppa -y 336 | echo "" 337 | echo -e "${GREEN}Installing Dependencies...${NC}" 338 | sudo apt-get update -y 339 | sudo apt-get upgrade -y 340 | echo "" 341 | # Perform distribution upgrade and remove unused packages 342 | sudo apt-get dist-upgrade -y 343 | sudo apt autoremove -y 344 | echo "" 345 | # Install required packages 346 | sudo apt-get install -y \ 347 | apt-transport-https \ 348 | ca-certificates \ 349 | curl \ 350 | htop \ 351 | gnupg \ 352 | git \ 353 | ufw \ 354 | tmux \ 355 | dialog \ 356 | rhash \ 357 | openssl \ 358 | wmctrl \ 359 | jq \ 360 | lsb-release \ 361 | dbus-x11 \ 362 | python3.8 python3.8-venv python3.8-dev python3-pip 363 | echo "" 364 | # Downloading Docker 365 | echo -e "${GREEN}Adding Docker PPA and installing Docker${NC}" 366 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg 367 | echo \ 368 | "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ 369 | $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 370 | echo "" 371 | sudo apt-get update -y 372 | echo "" 373 | sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose 374 | echo "" 375 | clear 376 | echo -e "${GREEN}Starting and enabling docker service${NC}" 377 | sudo systemctl start docker 378 | sudo systemctl enable docker 379 | 380 | # Adding Main user to the Docker group 381 | add_user_to_docker_group 382 | 383 | 384 | echo -e "${GREEN}Creating ${CUSTOM_PATH} Main-Folder${NC}" 385 | sudo mkdir "${CUSTOM_PATH}" 386 | echo "" 387 | echo -e "${GREEN}Generating jwt.hex secret${NC}" 388 | sudo sh -c "openssl rand -hex 32 | tr -d '\n' > ${CUSTOM_PATH}/jwt.hex" 389 | echo "" 390 | echo -e "${GREEN}Creating subFolders for ${ETH_CLIENT} and ${CONSENSUS_CLIENT}${NC}" 391 | sudo mkdir -p "${CUSTOM_PATH}/execution/$ETH_CLIENT" 392 | sudo mkdir -p "${CUSTOM_PATH}/consensus/$CONSENSUS_CLIENT" 393 | echo "" 394 | 395 | get_main_user 396 | 397 | echo -e "${GREEN}Creating the users ${ETH_CLIENT} and ${CONSENSUS_CLIENT} and setting permissions to the folders${NC}" 398 | 399 | sudo useradd -M -G docker $ETH_CLIENT 400 | sudo useradd -M -G docker $CONSENSUS_CLIENT 401 | 402 | sudo chown -R ${ETH_CLIENT}:docker "${CUSTOM_PATH}/execution" 403 | sudo chmod -R 750 "${CUSTOM_PATH}/execution" 404 | 405 | sudo chown -R ${CONSENSUS_CLIENT}:docker "${CUSTOM_PATH}/consensus/" 406 | sudo chmod -R 750 "${CUSTOM_PATH}/consensus" 407 | 408 | press_enter_to_continue 409 | 410 | 411 | echo "Creating shared group to access jwt.hex file" 412 | 413 | # Permission Madness 414 | # defining group for jwt.hex file 415 | sudo groupadd pls-shared 416 | sudo usermod -aG pls-shared ${ETH_CLIENT} 417 | sudo usermod -aG pls-shared ${CONSENSUS_CLIENT} 418 | 419 | # defining file permissions for jwt.hexSS 420 | #echo "ETH_CLIENT: ${ETH_CLIENT}" 421 | #echo "CUSTOM_PATH: ${CUSTOM_PATH}" 422 | #echo "File path: ${CUSTOM_PATH}/jwt.hex" 423 | #ls -l "${CUSTOM_PATH}/jwt.hex" 424 | 425 | sleep 1 426 | sudo chown ${ETH_CLIENT}:pls-shared ${CUSTOM_PATH}/jwt.hex 427 | sleep 1 428 | sudo chmod 640 ${CUSTOM_PATH}/jwt.hex 429 | sleep 1 430 | 431 | #ls -l "${CUSTOM_PATH}/jwt.hex" 432 | press_enter_to_continue 433 | #clear 434 | echo "" 435 | 436 | # Firewall Setup 437 | 438 | 439 | 440 | # Prompt for the Rules to add 441 | 442 | echo -e "${GREEN}Setting up firewall to allow access to SSH and port 8545 for localhost and private network connection to the RPC.${NC}" 443 | 444 | ip_range=$(get_ip_range) 445 | read -p "Do you want to allow access to the RPC and SSH from within your local network ($ip_range) only? (y/N): " local_network_choice 446 | read -p "Do you want to allow RPC (8545) access ?(y/N): " rpc_choice 447 | 448 | if [[ $rpc_choice == "y" ]]; then 449 | sudo ufw allow from 127.0.0.1 to any port 8545 proto tcp comment 'RPC Port' 450 | if [[ $local_network_choice == "y" ]]; then 451 | sudo ufw allow from $ip_range to any port 8545 proto tcp comment 'RPC Port for private IP range' 452 | fi 453 | fi 454 | 455 | read -p "Do you want to allow SSH access to this server? (y/N): " ssh_choice 456 | 457 | if [[ $ssh_choice == "y" ]]; then 458 | read -p "Enter SSH port (default is 22): " ssh_port 459 | if [[ $ssh_port == "" ]]; then 460 | ssh_port=22 461 | fi 462 | 463 | if [[ $local_network_choice == "n" ]]; then 464 | sudo ufw allow $ssh_port/tcp comment 'SSH Port' 465 | elif [[ $local_network_choice == "y" ]]; then 466 | sudo ufw allow from $ip_range to any port $ssh_port proto tcp comment 'SSH Port for private IP range' 467 | fi 468 | fi 469 | 470 | 471 | ############################################################################################################# 472 | 473 | echo "" 474 | echo -e "${GREEN}Setting Firewall to default, deny incomming and allow outgoing, enabling the Firewall${NC}" 475 | echo "" 476 | sudo ufw default deny incoming 477 | echo "" 478 | sudo ufw default allow outgoing 479 | echo "" 480 | # Allow inbound traffic for specific ports based on user choices 481 | if [ "$ETH_CLIENT_CHOICE" = "1" ]; then # as per https://geth.ethereum.org/docs/fundamentals/security 482 | sudo ufw allow 30303/tcp 483 | sudo ufw allow 30303/udp 484 | 485 | elif [ "$ETH_CLIENT_CHOICE" = "2" ]; then #as per https://github.com/ledgerwatch/erigon 486 | sudo ufw allow 30303/tcp 487 | sudo ufw allow 30303/udp 488 | sudo ufw allow 30304/tcp 489 | sudo ufw allow 30304/udp 490 | sudo ufw allow 42069/tcp 491 | sudo ufw allow 42069/udp 492 | sudo ufw allow 4000/udp 493 | sudo ufw allow 4001/tcp 494 | fi 495 | 496 | 497 | if [ "$CONSENSUS_CLIENT" = "prysm" ]; then #as per https://docs.prylabs.network/docs/prysm-usage/p2p-host-ip 498 | sudo ufw allow 13000/tcp 499 | sudo ufw allow 12000/udp 500 | elif [ "$CONSENSUS_CLIENT" = "lighthouse" ]; then #as per https://lighthouse-book.sigmaprime.io/faq.html 501 | sudo ufw allow 9000 502 | fi 503 | 504 | echo "" 505 | echo "enabling firewall now..." 506 | sudo ufw enable 507 | sleep 1 508 | clear 509 | echo "" 510 | echo "The Ethereum and Consensus clients will be started separately using two different scripts." 511 | echo "The start_execution.sh script will start the execution client." 512 | echo "The start_consensus.sh script will start the consensus (beacon) client." 513 | echo "The scripts will be generated in the directory \"$CUSTOM_PATH\"." 514 | echo "" 515 | echo "Generating scripts..." 516 | 517 | echo "" 518 | echo -e "${GREEN}Generating start_execution.sh script${NC}" 519 | cat > start_execution.sh << EOL 520 | #!/bin/bash 521 | 522 | echo "Starting ${ETH_CLIENT}" 523 | 524 | EOL 525 | 526 | if [ $ETH_CLIENT_CHOICE = "1" ]; then 527 | sudo docker pull registry.gitlab.com/pulsechaincom/go-pulse:latest 528 | cat >> start_execution.sh << EOL 529 | ${GETH_CMD} 530 | EOL 531 | fi 532 | 533 | if [ $ETH_CLIENT_CHOICE = "2" ]; then 534 | sudo docker pull registry.gitlab.com/pulsechaincom/erigon-pulse:latest 535 | cat >> start_execution.sh << EOL 536 | ${ERIGON_CMD} 537 | EOL 538 | fi 539 | 540 | if [ $ETH_CLIENT_CHOICE = "3" ]; then 541 | cat >> start_execution.sh << EOL 542 | ${ERIGON_CMD2} 543 | EOL 544 | fi 545 | 546 | chmod +x start_execution.sh 547 | sudo mv start_execution.sh "$CUSTOM_PATH" 548 | sudo chown $main_user:docker "$CUSTOM_PATH/start_execution.sh" 549 | 550 | echo "" 551 | echo -e "${GREEN}Generating start_consensus.sh script${NC}" 552 | cat > start_consensus.sh << EOL 553 | #!/bin/bash 554 | 555 | echo "Starting ${CONSENSUS_CLIENT}" 556 | 557 | EOL 558 | 559 | if [ "$CONSENSUS_CLIENT" = "prysm" ]; then 560 | sudo docker pull registry.gitlab.com/pulsechaincom/prysm-pulse/beacon-chain:latest 561 | sudo docker pull registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:latest 562 | cat >> start_consensus.sh << EOL 563 | ${PRYSM_CMD} 564 | 565 | EOL 566 | elif [ "$CONSENSUS_CLIENT" = "lighthouse" ]; then 567 | sudo docker pull registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest 568 | cat >> start_consensus.sh << EOL 569 | ${LIGHTHOUSE_CMD} 570 | 571 | EOL 572 | fi 573 | 574 | chmod +x start_consensus.sh 575 | sudo mv start_consensus.sh "$CUSTOM_PATH" 576 | sudo chown $main_user:docker "$CUSTOM_PATH/start_consensus.sh" 577 | 578 | echo "" 579 | echo -e "${GREEN}start_execution.sh and start_consensus.sh created successfully!${NC}" 580 | echo "" 581 | echo "" 582 | # Create the helper directory if it doesn't exist 583 | sudo mkdir -p "${CUSTOM_PATH}/helper" 584 | 585 | echo "" 586 | echo -e "${GREEN}copying over helper scripts${NC}" 587 | 588 | sudo cp setup_validator.sh "$CUSTOM_PATH/helper" 589 | sudo cp setup_monitoring.sh "$CUSTOM_PATH/helper" 590 | sudo cp functions.sh "$CUSTOM_PATH/helper" 591 | sudo cp helper/* "$CUSTOM_PATH/helper" 592 | 593 | # Permissions to folders 594 | sudo chmod -R +x $CUSTOM_PATH/helper/ 595 | sudo chmod -R 755 $CUSTOM_PATH/helper/ 596 | sudo chown -R $main_user:docker $CUSTOM_PATH/helper 597 | 598 | echo "" 599 | echo -e "${GREEN}Finished copying helper scripts${NC}" 600 | echo "" 601 | 602 | echo "" 603 | echo "Creating a small menu for general housekeeping" 604 | echo "" 605 | menu_script="$(script_launch_template)" 606 | menu_script+="$(printf '\nhelper_scripts_path="%s/helper"\n' "${CUSTOM_PATH}")" 607 | menu_script+="$(menu_script_template)" 608 | 609 | # Write the menu script to the helper directory 610 | echo "${menu_script}" | sudo tee "${CUSTOM_PATH}/menu.sh" > /dev/null 2>&1 611 | sudo chmod +x "${CUSTOM_PATH}/menu.sh" 612 | sudo cp "${CUSTOM_PATH}/menu.sh" /usr/local/bin/plsmenu > /dev/null 2>&1 613 | sudo chown -R $main_user:docker $CUSTOM_PATH/menu.sh 614 | 615 | echo "Menu script has been generated and written to ${CUSTOM_PATH}/menu.sh" 616 | 617 | read -p "Do you want to add Desktop-Shortcuts to a menu for general logging and node/validator settings (Recommended)? [Y/n] " log_choice 618 | echo "" 619 | echo -e "${RED}Note: You might have to right-click > allow launching on these${NC}" 620 | echo "" 621 | if [[ "$log_choice" =~ ^[Yy]$ || "$log_choice" == "" ]]; then 622 | create-desktop-shortcut ${CUSTOM_PATH}/helper/tmux_logviewer.sh tmux_LOGS 623 | create-desktop-shortcut ${CUSTOM_PATH}/helper/log_viewer.sh ui_LOGS 624 | #create-desktop-shortcut ${CUSTOM_PATH}/helper/restart_docker.sh Restart-clients 625 | create-desktop-shortcut ${CUSTOM_PATH}/helper/stop_docker.sh Stop-clients 626 | #create-desktop-shortcut ${CUSTOM_PATH}/helper/update_docker.sh Update-clients 627 | create-desktop-shortcut ${CUSTOM_PATH}/menu.sh Validator-Menu ${CUSTOM_PATH}/helper/LogoVector.svg 628 | fi 629 | 630 | echo "Menu generated and copied over to /usr/local/bin/plsmenu - you can open this helper menu by running plsmenu in the terminal" 631 | echo "" 632 | press_enter_to_continue 633 | 634 | 635 | ###### added features 636 | cron 637 | grace 638 | #beacon 639 | 640 | # setting 775 for the exeuction folder, in case of backup 641 | sudo chmod 775 -R $CUSTOM_PATH/execution 642 | 643 | # setting 777 for install_path 644 | sudo chmod 777 -R ${INSTALL_PATH} 645 | 646 | clear 647 | read -p "$(echo -e ${GREEN})Would you like to setup a validator? (y/n):$(echo -e ${NC}))" VALIDATOR_CHOICE 648 | echo "" 649 | if [ "$VALIDATOR_CHOICE" = "y" ]; then 650 | echo "" 651 | echo "Starting setup_validator.sh script" 652 | echo "" 653 | cd ${start_dir} 654 | #echo "debug" 655 | sudo chmod +x setup_validator.sh 656 | sudo ./setup_validator.sh 657 | exit 0 658 | 659 | else 660 | echo "Skipping creation of validator." 661 | echo "You can always create a validator later by running the ./setup_validator.sh script separately." 662 | echo "" 663 | fi 664 | 665 | read -p "Do you want to start the execution and consensus scripts now? [Y/n] " choice 666 | 667 | # Check if the user wants to run the scripts 668 | if [[ "$choice" =~ ^[Yy]$ || "$choice" == "" ]]; then 669 | 670 | # Generate the command to start the scripts 671 | command1="${CUSTOM_PATH}/start_execution.sh > /dev/null 2>&1 &" 672 | command2="${CUSTOM_PATH}/start_consensus.sh > /dev/null 2>&1 &" 673 | 674 | # Print the command to the terminal 675 | echo "Running command: $command1" 676 | echo "Running command: $command2" 677 | 678 | # Run the command 679 | eval $command1 680 | sleep 1 681 | eval $command2 682 | sleep 1 683 | fi 684 | 685 | clear 686 | echo "" 687 | echo -e "${GREEN}Congratulations, node installation/setup is now complete.${NC}" 688 | echo "" 689 | display_credits 690 | 691 | # Inform the user that a reboot is required, making 'Yes' the default choice 692 | echo "" 693 | echo "The system now requires a reboot to complete the setup. Would you like to reboot now? (Yes/no)" 694 | 695 | read -p "" user_response 696 | 697 | # Treat an empty response as 'yes' 698 | if [[ -z "$user_response" ]] || [[ "$user_response" == "yes" ]] || [[ "$user_response" == "y" ]]; then 699 | echo "Rebooting the system..." 700 | sleep 1 701 | sudo reboot 702 | else 703 | echo "Please reboot the system manually to complete the setup." 704 | exit 0 705 | fi 706 | exit 0 707 | --------------------------------------------------------------------------------