-
Notifications
You must be signed in to change notification settings - Fork 12
/
functions.sh
1528 lines (1341 loc) · 50.8 KB
/
functions.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#Vars for network:
set_network_variables() {
if [[ $1 == "testnet" ]]; then
CHECKPOINT="https://checkpoint.v4.testnet.pulsechain.com"
LAUNCHPAD_URL="https://launchpad.v4.testnet.pulsechain.com"
EXECUTION_NETWORK_FLAG="pulsechain-testnet-v4"
PRYSM_NETWORK_FLAG="pulsechain-testnet-v4"
LIGHTHOUSE_NETWORK_FLAG="pulsechain_testnet_v4"
DEPOSIT_CLI_NETWORK="pulsechain-testnet-v4"
else
CHECKPOINT="https://checkpoint.pulsechain.com"
LAUNCHPAD_URL="https://launchpad.pulsechain.com"
EXECUTION_NETWORK_FLAG="pulsechain"
PRYSM_NETWORK_FLAG="pulsechain"
LIGHTHOUSE_NETWORK_FLAG="pulsechain"
DEPOSIT_CLI_NETWORK="pulsechain"
fi
export CHECKPOINT
export LAUNCHPAD_URL
export EXECUTION_NETWORK_FLAG
export PRYSM_NETWORK_FLAG
export LIGHTHOUSE_NETWORK_FLAG
export DEPOSIT_CLI_NETWORK
}
clear
check_and_set_network_variables() {
if [[ -z $EXECUTION_NETWORK_FLAG ]]; then
echo ""
echo "+-----------------+"
echo "| Choose network: |"
echo "+-----------------+"
echo "| 1) Mainnet |"
echo "| |"
echo "| 2) Testnet |"
echo "+-----------------+"
echo ""
read -p "Enter your choice (1 or 2): " -r choice
echo ""
case $choice in
1)
set_network_variables "mainnet"
;;
2)
set_network_variables "testnet"
;;
*)
echo "Invalid choice. Exiting."
exit 1
;;
esac
fi
}
function logviewer_prompt() {
local log_it choice
read -e -p "$(echo -e "${GREEN}Would you like to start the logviewer to monitor the client logs? [y/n]:${NC}")" log_it
if [[ "$log_it" =~ ^[Yy]$ ]]; then
while true; do
echo "Choose a log viewer:"
echo "1. GUI/TAB Based Logviewer (serperate tabs; easy)"
echo "2. TMUX Logviewer (AIO logs; advanced)"
read -p "Enter your choice (1 or 2): " choice
case $choice in
1)
${INSTALL_PATH}/helper/log_viewer.sh
break
;;
2)
${INSTALL_PATH}/helper/tmux_logviewer.sh
break
;;
*)
echo "Invalid choice. Please enter 1 or 2."
;;
esac
done
fi
}
function to_valid_erc20_address() {
local input_address="$1"
local input_address_lowercase="${input_address,,}" # Convert to lowercase
# Calculate the Keccak-256 hash of the lowercase input address using openssl
local hash=$(echo -n "${input_address_lowercase}" | openssl dgst -sha3-256 -binary | xxd -p -c 32)
# Build the checksum address
local checksum_address="0x"
for ((i=0;i<${#input_address_lowercase};i++)); do
char="${input_address_lowercase:$i:1}"
if [ "${char}" != "${char^^}" ]; then
checksum_address+="${input_address:$i:1}"
else
checksum_address+="${hash:$((i/2)):1}"
fi
done
echo "$checksum_address"
}
function restart_tmux_logs_session() {
# Check if the "logs" tmux session is running
if tmux has-session -t logs 2>/dev/null; then
echo "Tmux session 'logs' is running, restarting it."
press_enter_to_continue
start_script tmux_logviewer
#echo "Tmux session 'logs' has been (re)started."
# Kill the existing "logs" session
tmux kill-session -t logs
else
echo "Tmux session 'logs' is not running."
fi
}
function reboot_advice() {
echo "Initial setup completed. To get all permissions right, it is recommended to reboot your system now ."
read -p "Do you want to reboot now? [y/n]: " choice
if [ "$choice" == "y" ]; then
sudo reboot
elif [ "$choice" == "n" ]; then
echo "Please remember to reboot your system later."
else
echo "Invalid option. Please try again."
reboot_advice
fi
}
while getopts "rl" option; do
case "$option" in
r)
sudo reboot
;;
l)
echo "Please remember to reboot your system later."
;;
*)
reboot_advice
;;
esac
done
function get_user_choices() {
echo "Choose your Validator Client"
echo "based on your consensus/beacon Client"
echo ""
echo "1. Lighthouse (Authors choice)"
echo "2. Prysm"
echo ""
read -p "Enter your choice (1 or 2): " client_choice
# Validate user input for client choice
while [[ ! "$client_choice" =~ ^[1-2]$ ]]; do
echo "Invalid input. Please enter a valid choice (1 or 2): "
read -p "Enter your choice (1 or 2): " client_choice
done
echo ""
echo "Is this a first-time setup or are you adding to an existing setup?"
echo ""
echo "1. First-Time Validator Setup"
echo "2. Add or Import to an Existing setup"
echo ""
read -p "Enter your choice (1 or 2): " setup_choice
# Validate user input for setup choice
while [[ ! "$setup_choice" =~ ^[1-2]$ ]]; do
echo "Invalid input. Please enter a valid choice (1 or 2): "
read -p "Enter your choice (1 or 2): " setup_choice
done
#echo "${client_choice} ${setup_choice}"
}
function press_enter_to_continue(){
echo ""
echo "Press Enter to continue"
read -p ""
echo ""
}
function stop_docker_container() {
container_name_or_id="$1"
container_status=$(docker inspect --format "{{.State.Status}}" "$container_name_or_id" 2>/dev/null)
if [ "$container_status" == "running" ]; then
echo "Stopping container with name or ID: $container_name_or_id"
sudo docker stop -t 180 "$container_name_or_id"
sudo docker container prune -f
elif [ -n "$container_status" ]; then
echo "Container $container_name_or_id is not running."
else
echo "No container found with name or ID: $container_name_or_id"
fi
}
function display_credits() {
echo ""
echo "Brought to you by:"
echo " ██████__██_██████__███████_██_______█████__██____██_███████_██████__"
echo " ██___██_██_██___██_██______██______██___██__██__██__██______██___██_"
echo " ██___██_██_██████__███████_██______███████___████___█████___██████__"
echo " ██___██_██_██___________██_██______██___██____██____██______██___██_"
echo " ██████__██_██______███████_███████_██___██____██____███████_██___██_"
echo -e "${GREEN}For Donations use \nERC20: 0xCB00d822323B6f38d13A1f951d7e31D9dfDED4AA${NC}"
echo ""
}
function tab_autocomplete(){
# Enable tab autocompletion for the read command if line editing is enabled
if [ -n "$BASH_VERSION" ] && [ -n "$PS1" ] && [ -t 0 ]; then
bind '"\t":menu-complete'
fi
}
function common_task_software_check(){
# Check if req. software is installed
python_check=$(python3.10 --version 2>/dev/null)
docker_check=$(docker --version 2>/dev/null)
docker_compose_check=$(docker-compose --version 2>/dev/null)
openssl_check=$(openssl version 2>/dev/null)
# Install the req. software only if not already installed
if [[ -z "${python_check}" || -z "${docker_check}" || -z "${docker_compose_check}" || -z "${openssl_check}" ]]; then
echo "Installing required packages..."
sudo add-apt-repository ppa:deadsnakes/ppa -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get dist-upgrade -y
sudo apt autoremove -y
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
git \
b2sum \
ufw \
openssl \
lsb-release \
python3.10 python3.10-venv python3.10-dev python3-pip \
docker-ce docker-ce-cli containerd.io docker-compose
else
echo ""
echo "Required packages are already installed."
echo ""
fi
}
function graffiti_setup() {
echo ""
while true; do
read -e -p "$(echo -e "${GREEN}Please enter your desired graffiti. Ensure that it does not exceed 32 characters (default: DipSlayer):${NC}")" user_graffiti
# Set the default value for graffiti if the user enters nothing
if [ -z "$user_graffiti" ]; then
user_graffiti="DipSlayer"
break
# Check if the input length is within the 32 character limit
elif [ ${#user_graffiti} -le 32 ]; then
break
else
echo -e "${RED}The graffiti you entered is too long. Please ensure it does not exceed 32 characters.${NC}"
fi
done
# Enclose the user_graffiti in double quotes
user_graffiti="\"${user_graffiti}\""
}
function set_install_path() {
echo ""
read -e -p "$(echo -e "${GREEN}Please specify the directory for storing the validator data. Press Enter to use the default (/blockchain):${NC} ")" INSTALL_PATH
if [ -z "$INSTALL_PATH" ]; then
INSTALL_PATH="/blockchain"
fi
if [ ! -d "$INSTALL_PATH" ]; then
sudo mkdir -p "$INSTALL_PATH"
echo "Created the directory: $INSTALL_PATH"
else
echo "The directory already exists: $INSTALL_PATH"
fi
}
function get_install_path() {
echo ""
read -e -p "$(echo -e "${GREEN}Please specify the directory where your blockchain data root folder is located. Press Enter to use the default (/blockchain): ${NC} ")" INSTALL_PATH
if [ -z "$INSTALL_PATH" ]; then
INSTALL_PATH="/blockchain"
fi
}
function get_active_network_device() {
interface=$(ip route get 8.8.8.8 | awk '{print $5}')
echo "Your online network interface is: $interface"
}
function cd_into_staking_cli() {
cd ${INSTALL_PATH}/staking-deposit-cli
sudo python3 setup.py install > /dev/null 2>&1
}
function network_interface_DOWN() {
get_active_network_device
echo "Shutting down Network-Device ${interface} ..."
sudo ip link set $interface down
echo "The network interface has been shutdown. It will be put back online after this process."
}
function start_scripts_first_time() {
# Check if the user wants to run the scripts
read -e -p "Do you want to run the scripts to start execution, consensus, and validator? (y/n) " choice
if [[ "$choice" =~ ^[Yy]$ || "$choice" == "" ]]; then
# Generate the commands to start the scripts
commands=(
"sudo ${INSTALL_PATH}/start_execution.sh > /dev/null 2>&1 &"
"sudo ${INSTALL_PATH}/start_consensus.sh > /dev/null 2>&1 &"
"sudo ${INSTALL_PATH}/start_validator.sh > /dev/null 2>&1 &"
)
# Run the commands
for cmd in "${commands[@]}"; do
echo "Running command: $cmd"
eval "$cmd"
sleep 1
done
fi
}
function clear_bash_history() {
echo "Clearing bash history now..."
history -c && history -w
echo "Bash history cleared!"
}
function network_interface_UP() {
echo "Restarting Network-Interface ${interface} ..."
sudo ip link set $interface up
echo "Network interface put back online"
}
function create_user() {
target_user=$1
if id "$target_user" >/dev/null 2>&1; then
echo "User $target_user already exists."
else
sudo useradd -MG docker "$target_user"
echo "User $target_user has been created and added to the docker group."
fi
}
function clone_staking_deposit_cli() {
target_directory=$1
# Check if the staking-deposit-cli folder already exists
if [ -d "${target_directory}/staking-deposit-cli" ]; then
read -p "The staking-deposit-cli folder already exists. Do you want to delete it and clone the latest version? (y/N): " confirm_delete
if [ "$confirm_delete" == "y" ] || [ "$confirm_delete" == "Y" ]; then
sudo rm -rf "${target_directory}/staking-deposit-cli"
else
echo "Skipping the cloning process as the user chose not to delete the existing folder."
return
fi
fi
while true; do
# Clone the staking-deposit-cli repository
if sudo git clone https://gitlab.com/pulsechaincom/staking-deposit-cli.git "${target_directory}/staking-deposit-cli"; then
echo "Cloned staking-deposit-cli repository into ${target_directory}/staking-deposit-cli"
sudo chown -R $main_user:docker "${target_directory}/staking-deposit-cli"
break
else
echo ""
echo "Failed to clone staking-deposit-cli repository. Please check your internet connection and try again."
echo ""
echo "You can relaunch the script at any time with ./setup_validator.sh from the install folder."
echo ""
read -p "Press 'r' to retry, any other key to exit: " choice
if [ "$choice" != "r" ]; then
exit 1
fi
fi
done
}
function Staking_Cli_launch_setup() {
# Check Python version (>= Python3.8)
echo "running staking-cli Checkup"
sudo chmod -R 777 "${INSTALL_PATH}/staking-deposit-cli"
cd "${INSTALL_PATH}/staking-deposit-cli"
python3_version=$(python3 -V 2>&1 | awk '{print $2}')
required_version="3.8"
if [ "$(printf '%s\n' "$required_version" "$python3_version" | sort -V | head -n1)" = "$required_version" ]; then
echo "Python version is greater or equal to 3.8"
else
echo "Error: Python version must be 3.8 or higher"
exit 1
fi
sudo pip3 install -r "${INSTALL_PATH}/staking-deposit-cli/requirements.txt" > /dev/null 2>&1
#read -p "debug 1"
sudo python3 "${INSTALL_PATH}/staking-deposit-cli/setup.py" install > /dev/null 2>&1
#read -p "debug 2"
}
function create_subfolder() {
subdirectory=$1
sudo mkdir -p "${INSTALL_PATH}/${subdirectory}"
sudo chmod 777 "${INSTALL_PATH}/${subdirectory}"
echo "Created directory: ${install_path}/${subdirectory}"
}
function confirm_prompt() {
message="$1"
while true; do
echo "$message"
read -p "Do you confirm? (y/n): " yn
case $yn in
[Yy]* )
# User confirmed, return success (0)
return 0
;;
[Nn]* )
# User did not confirm, return failure (1)
return 1
;;
* )
# Invalid input, ask again
echo "Please answer 'y' (yes) or 'n' (no)."
;;
esac
done
}
function create_prysm_wallet_password() {
password_file="${INSTALL_PATH}/wallet/pw.txt"
if [ -f "$password_file" ]; then
echo ""
echo -e "${RED}Warning: A password file already exists at ${password_file}${NC}"
echo ""
read -n 1 -p "Do you want to continue and overwrite the existing password file? (y/n) [n]: " confirm
if [ "$confirm" != "y" ]; then
echo "Cancelled password creation."
return
fi
fi
echo ""
echo ""
echo -e "Please enter your Prysm Wallet password now."
echo ""
echo "This has nothing to do with the 24-word SeedPhrase that Staking-Cli will output during key-generation."
echo "Unlocking your wallet is necessary for the Prysm Validator Client to function."
echo ""
while true; do
echo "Please enter a password (must be at least 8 characters):"
read -s password
if [[ ${#password} -ge 8 ]]; then
break
else
echo "Error: Password must be at least 8 characters long."
fi
done
echo "$password" > "$password_file"
}
function check_and_pull_lighthouse() {
# Check if the Lighthouse validator Docker image is present
lighthouse_image_exists=$(sudo docker images registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest -q)
# If the image does not exist, pull the image
if [ -z "$lighthouse_image_exists" ]; then
echo ""
echo "Lighthouse validator Docker image not found. Pulling the latest image..."
sudo docker pull registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest
echo ""
else
echo ""
echo "Lighthouse validator Docker image is already present."
echo ""
fi
}
function check_and_pull_prysm_validator() {
# Check if the Prysm validator Docker image is present
prysm_image_exists=$(sudo docker images registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest -q)
# If the image does not exist, pull the image
if [ -z "$prysm_image_exists" ]; then
echo ""
echo "Prysm validator Docker image not found. Pulling the latest image..."
sudo docker pull registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest
echo ""
else
echo ""
fi
}
function stop_and_prune_validator_import(){
sudo docker stop validator_import > /dev/null 2>&1
sudo docker container prune -f > /dev/null 2>&1
}
function stop_docker_image(){
echo "To import the keys into an existing setup, we need to stop the running validator container first."
image=$1
sudo docker stop -t 300 ${image} > /dev/null 2>&1
sudo docker prune -f > /dev/null 2>&1
}
function start_script(){
target=$1
echo ""
echo -e "Restarting ${target}"
bash "${INSTALL_PATH}/helper/${target}.sh"
echo "${target} container restartet"
}
#function import_lighthouse_validator() {
# stop_and_prune_validator_import
# echo ""
# docker pull registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest
# echo ""
# sudo docker run -it \
# --name validator_import \
# --network=host \
# -v ${INSTALL_PATH}:/blockchain \
# -v ${INSTALL_PATH}/validator_keys:/keys \
# registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest \
# lighthouse \
# --network=${LIGHTHOUSE_NETWORK_FLAG} \
# account validator import \
# --directory=/keys \
# --datadir=/blockchain
# stop_and_prune_validator_import
#}
function import_lighthouse_validator() {
stop_and_prune_validator_import
echo ""
# Prompt the user
echo -n "Are you importing multiple validators with the same password? (y/N): "
read user_response
# If nothing is entered, default to "N"
if [ -z "$user_response" ]; then
user_response="N"
fi
docker pull registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest
echo ""
# Base command
cmd="sudo docker run -it \
--name validator_import \
--network=host \
-v ${INSTALL_PATH}:/blockchain \
-v ${INSTALL_PATH}/validator_keys:/keys \
registry.gitlab.com/pulsechaincom/lighthouse-pulse:latest \
lighthouse \
--network=${LIGHTHOUSE_NETWORK_FLAG} \
account validator import \
--directory=/keys \
--datadir=/blockchain"
# Conditionally add the --reuse-password flag
if [ "${user_response,,}" == "y" ]; then
cmd="$cmd \
--reuse-password"
fi
# Execute the command
eval $cmd
stop_and_prune_validator_import
}
function import_prysm_validator() {
stop_and_prune_validator_import
echo ""
docker pull registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest
docker pull registry.gitlab.com/pulsechaincom/prysm-pulse/prysmctl:latest
echo ""
if [ -f "${INSTALL_PATH}/wallet/direct/accounts/all-accounts.keystore.json" ]; then
sudo chmod -R 0600 "${INSTALL_PATH}/wallet/direct/accounts/all-accounts.keystore.json"
fi
docker run --rm -it \
--name validator_import \
-v $INSTALL_PATH/validator_keys:/keys \
-v $INSTALL_PATH/wallet:/wallet \
registry.gitlab.com/pulsechaincom/prysm-pulse/validator:latest \
accounts import \
--${PRYSM_NETWORK_FLAG} \
--keys-dir=/keys \
--wallet-dir=/wallet \
--wallet-password-file=/wallet/pw.txt
stop_and_prune_validator_import
}
function deposit_upload_info() {
echo ""
echo -e "Upload your 'deposit_data-xxxyyyzzzz.json' to ${LAUNCHPAD_URL} after the full chain sync. ${RED}Uploading before completion may result in slashing.${NC}"
echo ""
echo -e "${RED}For security reasons, it's recommended to store the validator_keys in a safe, offline location after importing it.${NC}"
echo ""
press_enter_to_continue
}
function warn_network() {
echo ""
echo "Enhance security by generating new keys or restoring them from a seed phrase (mnemonic) offline."
echo ""
echo -e "${RED}WARNING:${NC} Disabling your network interface may result in loss of remote"
echo -e " access to your machine. Ensure you have an alternative way to"
echo -e " access your machine, such as a local connection or a remote"
echo -e " VPS terminal, before proceeding."
echo -e ""
echo -e "${RED}IMPORTANT:${NC} Proceed with caution, as disabling the network interface"
echo -e " without any other means of access may leave you unable to"
echo -e " access your machine remotely. Make sure you fully understand"
echo -e " the consequences and have a backup plan in place before taking"
echo -e " this step."
echo ""
echo -e "Would you like to disable the network interface during the key"
echo -e "generation process? This increases security, but ${RED}may affect remote"
echo -e "access temporarily${NC}"
echo ""
read -e -p "Please enter 'y' to confirm or 'n' to decline (default: n): " network_off
network_off=${network_off:-n}
}
function get_fee_receipt_address() {
read -e -p "$(echo -e "${GREEN}Enter fee-receipt address (leave blank for my donation address; can be changed later in start_validator.sh):${NC}")" fee_wallet
echo ""
# Use a regex pattern to validate the input wallet address
if [[ -z "${fee_wallet}" ]] || ! [[ "${fee_wallet}" =~ ^0x[a-fA-F0-9]{40}$ ]]; then
fee_wallet="0xCB00d822323B6f38d13A1f951d7e31D9dfDED4AA"
echo " - Using default fee-receiption address: ${fee_wallet}"
else
echo " - Using provided fee-receiption address: ${fee_wallet}"
fi
}
function get_user_choices_monitor() {
local client_choice
while true; do
echo "Choose your Client"
echo ""
echo "1. Lighthouse"
echo "2. Prysm"
echo ""
read -p "Enter your choice (1 or 2): " client_choice
case $client_choice in
1|2)
break
;;
*)
echo "Invalid choice. Please enter 1 or 2."
;;
esac
done
#echo "${client_choice}"
}
function add_user_to_docker_group() {
# Check if the script is run as root
if [ "$EUID" -eq 0 ]; then
# Get the main non-root user
local main_user=$(logname)
# Check if the main user is already in the docker group
if id -nG "${main_user}" | grep -qw "docker"; then
echo "User ${main_user} is already a member of the docker group."
else
# Add the main user to the docker group
usermod -aG docker "${main_user}"
echo "User ${main_user} added to the docker group. Please log out and log back in for the changes to take effect."
fi
else
# Get the current user
local current_user=$(whoami)
# Check if the user is already in the docker group
if id -nG "${current_user}" | grep -qw "docker"; then
echo "User ${current_user} is already a member of the docker group."
else
# Add the user to the docker group
sudo usermod -aG docker "${current_user}"
echo "User ${current_user} added to the docker group. Please log out and log back in for the changes to take effect."
fi
fi
}
function create-desktop-shortcut() {
# Check if at least two arguments are provided
if [[ $# -lt 2 ]]; then
echo "Usage: create-desktop-shortcut <target-shell-script> <shortcut-name> [icon-path]"
return 1
fi
# get main user
main_user=$(logname || echo $SUDO_USER || echo $USER)
# check if desktop directory exists for main user
desktop_dir="/home/$main_user/Desktop"
if [ ! -d "$desktop_dir" ]; then
echo "Desktop directory not found for user $main_user"
return 1
fi
# check if script file exists
if [ ! -f "$1" ]; then
echo "Script file not found: $1"
return 1
fi
# set shortcut name
shortcut_name=${2:-$(basename "$1" ".sh")}
# set terminal emulator command
terminal_emulator="gnome-terminal -- bash -c"
# set icon path if provided and file exists
icon_path=""
if [[ -n "$3" ]] && [[ -f "$3" ]]; then
icon_path="Icon=$3"
fi
# create shortcut file
cat > "$desktop_dir/$shortcut_name.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=$shortcut_name
Exec=$terminal_emulator '$1; exec bash'
Terminal=true
$icon_path
EOF
# make shortcut executable
chmod +x "$desktop_dir/$shortcut_name.desktop"
echo "Desktop shortcut created: $desktop_dir/$shortcut_name.desktop"
}
# Helper script function template
function script_launch_template() {
cat <<-'EOF'
script_launch() {
local script_name=$1
local script_path="${helper_scripts_path}/${script_name}"
if [[ -x ${script_path} ]]; then
${script_path}
else
echo "Error: ${script_path} not found or not executable."
exit 1
fi
}
EOF
}
function menu_script_template() {
cat <<-'EOF' | sed "s|@@CUSTOM_PATH@@|$CUSTOM_PATH|g"
#!/bin/bash
CUSTOM_PATH="@@CUSTOM_PATH@@"
VERSION="1.4d"
script_launch() {
echo "Launching script: ${CUSTOM_PATH}/helper/$1"
${CUSTOM_PATH}/helper/$1
}
main_menu() {
while true; do
main_opt=$(dialog --stdout --title "Main Menu $VERSION" --backtitle "created by DipSlayer 0xCB00d822323B6f38d13A1f951d7e31D9dfDED4AA" --menu "Choose an option:" 0 0 0 \
"Logviewer" "Start different Logviewer" \
"Clients Menu" "Execution, Beacon and Validator Clients" \
"Info and KeyManagment" "Tools for Key Management and Node/Validator Information" \
"System" "Update, Reboot, shutdown, Backup & Restore" \
"-" ""\
"exit" "Exit the program")
case $? in
0)
case $main_opt in
"Logviewer")
logviewer_submenu
;;
"Clients Menu")
client_actions_submenu
;;
"Info and KeyManagment")
validator_setup_submenu
;;
"System")
system_submenu
;;
"-")
;;
"exit")
clear
break
;;
esac
;;
1)
break
;;
esac
done
}
logviewer_submenu() {
while true; do
lv_opt=$(dialog --stdout --title "Logviewer Menu $VERSION" --stdout --backtitle "created by DipSlayer 0xCB00d822323B6f38d13A1f951d7e31D9dfDED4AA" --menu "Choose an option:" 0 0 0 \
"Tabbed-Terminal Logs" "Multiple Tabs" \
"Tmux-Style Logs" "Single Window" \
"-" ""\
"back" "Back to main menu")
case $? in
0)
case $lv_opt in
"Tabbed-Terminal Logs")
clear && script_launch "log_viewer.sh"
;;
"Tmux-Style Logs")
clear && script_launch "tmux_logviewer.sh"
;;
"-")
;;
"back")
break
;;
esac
;;
1)
break
;;
esac
done
}
client_actions_submenu() {
while true; do
ca_opt=$(dialog --stdout --title "Client Menu $VERSION" --backtitle "created by DipSlayer 0xCB00d822323B6f38d13A1f951d7e31D9dfDED4AA" --menu "Choose an option:" 0 0 0 \
"Execution-Client Menu" ""\
"Beacon-Client Menu" ""\
"Validator-Client Menu" ""\
"-" ""\
"Start all Clients" ""\
"Stop all Clients" ""\
"Restart all Clients" ""\
"Update all Clients" ""\
"-" ""\
"back" "Back to main menu")
case $? in
0)
case $ca_opt in
"Execution-Client Menu")
execution_submenu
;;
"Beacon-Client Menu")
beacon_submenu
;;
"Validator-Client Menu")
validator_submenu
;;
"-")
;;
"Start all Clients")
clear
${CUSTOM_PATH}/start_execution.sh
${CUSTOM_PATH}/start_consensus.sh
${CUSTOM_PATH}/start_validator.sh
;;
"Stop all Clients")
clear && script_launch "stop_docker.sh"
;;
"Restart all Clients")
clear && script_launch "stop_docker.sh"
${CUSTOM_PATH}/start_execution.sh
${CUSTOM_PATH}/start_consensus.sh
${CUSTOM_PATH}/start_validator.sh
;;
"Update all Clients")
clear && script_launch "update_docker.sh"
${CUSTOM_PATH}/start_execution.sh
${CUSTOM_PATH}/start_consensus.sh
${CUSTOM_PATH}/start_validator.sh
;;
"back")
break
;;
esac
;;
1)
break
;;
esac
done
}
execution_submenu() {
while true; do
exe_opt=$(dialog --stdout --title "Execution-Client Menu $VERSION" --backtitle "created by DipSlayer 0xCB00d822323B6f38d13A1f951d7e31D9dfDED4AA" --menu "Choose an option:" 0 0 0 \
"Start Execution-Client" "" \
"Stop Execution-Client" "" \
"Restart Execution-Client" "" \
"-" ""\
"Edit Execution-Client Config" "" \
"Show Logs" "" \
"Update Execution-Client" "" \
"-" ""\
"back" "Back to Client Actions Menu")
case $? in
0)
case $exe_opt in
"Start Execution-Client")
clear && ${CUSTOM_PATH}/start_execution.sh
;;
"Stop Execution-Client")
clear && sudo docker stop -t 300 execution
sleep 1
sudo docker container prune -f
;;
"Restart Execution-Client")
clear && sudo docker stop -t 300 execution
sleep 1
sudo docker container prune -f
clear && ${CUSTOM_PATH}/start_execution.sh
;;
"Edit Execution-Client Config")
clear && sudo nano "${CUSTOM_PATH}/start_execution.sh"
;;
"Show Logs")
clear && sudo docker logs -f execution
;;
"Update Execution-Client")
clear && docker stop -t 300 execution
docker container prune -f && docker image prune -f
docker rmi registry.gitlab.com/pulsechaincom/go-pulse > /dev/null 2>&1
docker rmi registry.gitlab.com/pulsechaincom/go-erigon > /dev/null 2>&1
${CUSTOM_PATH}/start_execution.sh
;;