devnet.sh
1 #!/bin/bash 2 3 if [[ -n "$TMUX" ]]; then 4 echo "Detected nested tmux session. Try again after unsetting \$TMUX, e.g., using \`unset TMUX\` in bash." 5 exit 1 6 fi 7 8 # Read the total number of validators from the user or use a default value of 4 9 read -p "Enter the total number of validators (default: 4): " total_validators 10 total_validators=${total_validators:-4} 11 12 # Read the total number of clients from the user or use a default value of 2 13 read -p "Enter the total number of clients (default: 2): " total_clients 14 total_clients=${total_clients:-2} 15 16 # Read the network ID from user or use a default value of 1 17 read -p "Enter the network ID (mainnet = 0, testnet = 1, canary = 2) (default: 1): " network_id 18 network_id=${network_id:-1} 19 20 # Ask the user if they want to run 'cargo install --locked --path .' or use a pre-installed binary 21 read -p "Do you want to run 'cargo install --locked --path .' to build the binary? (y/n, default: y): " build_binary 22 build_binary=${build_binary:-y} 23 24 # Ask the user whether to clear the existing ledger history 25 read -p "Do you want to clear the existing ledger history? (y/n, default: n): " clear_ledger 26 clear_ledger=${clear_ledger:-n} 27 28 # Log verbosity is set to 1 (DEBUG) by default. 29 verbosity=1 30 31 # Binary path set to "" by default (using installed binary) 32 binary_path="" 33 34 if [[ $build_binary == "y" ]]; then 35 # Ask the user if they want to enable validator telemetry 36 read -p "Do you want to enable validator telemetry? (y/n, default: y): " enable_telemetry 37 enable_telemetry=${enable_telemetry:-y} 38 39 # Ask the user for additional crate features (comma-separated) 40 read -p "Enter crate features to enable (comma separated, default: test_network): " crate_features 41 crate_features=${crate_features:-test_network} 42 43 # Build command 44 build_cmd="cargo install --locked --path ." 45 46 # Add the telemetry feature if requested 47 if [[ $enable_telemetry == "y" ]]; then 48 build_cmd+=" --features telemetry" 49 fi 50 51 # Add any extra features if provided 52 if [[ -n $crate_features ]]; then 53 # If telemetry was also enabled, append with a comma separator 54 if [[ $enable_telemetry == "y" ]]; then 55 build_cmd+=",${crate_features}" 56 else 57 build_cmd+=" --features ${crate_features}" 58 fi 59 fi 60 61 # Build command 62 echo "Running build command: \"$build_cmd\"" 63 eval "$build_cmd" || exit 1 64 else 65 # Ask the user whether to use a custom relative path 66 read -p "Do you want to run snarkos from a relative path? (e.g. ./target/debug/, defaults to the installed binary): " binary_path 67 binary_path=${binary_path:-""} 68 fi 69 70 # Clear the ledger logs for each validator if the user chooses to clear ledger 71 if [[ $clear_ledger == "y" ]]; then 72 # Create an array to store background processes 73 clean_processes=() 74 75 for ((index = 0; index < $((total_validators + total_clients)); index++)); do 76 # Run 'snarkos clean' for each node in the background 77 "${binary_path}snarkos" clean "--network=$network_id" "--dev=$index" "--dev-num-validators=$total_validators" & 78 79 # Store the process ID of the background task 80 clean_processes+=($!) 81 done 82 83 # Wait for all 'snarkos clean' processes to finish 84 for process_id in "${clean_processes[@]}"; do 85 wait "$process_id" 86 done 87 fi 88 89 # Create a timestamp-based directory for log files 90 log_dir=".logs-$(date +"%Y%m%d%H%M%S")" 91 mkdir -p "$log_dir" 92 93 # Create a new tmux session named "devnet" 94 tmux new-session -d -s "devnet" -n "validator-0" 95 if [[ $? -ne 0 ]]; then 96 echo "Failed to create new TMUX session." 97 exit 1 98 fi 99 100 # Get the tmux's base-index for windows 101 # we have to create all windows with index offset by this much 102 index_offset="$(tmux show-option -gv base-index)" 103 if [ -z "$index_offset" ]; then 104 index_offset=0 105 fi 106 107 # Generate validator indices from 0 to (total_validators - 1) 108 validator_indices=($(seq 0 $((total_validators - 1)))) 109 110 # Loop through the list of validator indices and create a new window for each 111 for validator_index in "${validator_indices[@]}"; do 112 # Generate a unique and incrementing log file name based on the validator indexi 113 name="validator-$validator_index" 114 log_file="$log_dir/$name.log" 115 window_index=$((validator_index + index_offset)) 116 metrics_port=$((validator_index + 9000)) 117 118 if [ "$validator_index" -ne 0 ]; then 119 # We don't need to create a window for the first validator because the tmux session already starts with one window. 120 tmux new-window -t "devnet:$window_index" -n $name 121 fi 122 123 # Send the command to start the validator to the new window and capture output to the log file 124 tmux send-keys -t "devnet:$window_index" "${binary_path}snarkos start --dev-num-clients $total_clients --nodisplay --network $network_id --dev $validator_index --dev-num-validators $total_validators --validator --logfile $log_file --verbosity $verbosity --metrics --metrics-ip=0.0.0.0:$metrics_port --no-dev-txs" C-m 125 done 126 127 if [ "$total_clients" -ne 0 ]; then 128 # Generate client indices from 0 to (total_clients - 1) 129 client_indices=($(seq 0 $((total_clients - 1)))) 130 131 # Loop through the list of client indices and create a new window for each 132 for client_index in "${client_indices[@]}"; do 133 # Generate a unique and incrementing log file name based on the client index 134 name="client-$client_index" 135 log_file="$log_dir/$name.log" 136 137 window_index=$((client_index + total_validators + index_offset)) 138 139 # Create a new window with a unique name 140 tmux new-window -t "devnet:$window_index" -n $name 141 142 # Send the command to start the client to the new window and capture output to the log file 143 tmux send-keys -t "devnet:$window_index" "${binary_path}snarkos start --nodisplay --network $network_id --dev $window_index --dev-num-validators $total_validators --client --logfile $log_file --verbosity $verbosity" C-m 144 done 145 fi 146 147 # Attach to the tmux session to view and interact with the windows 148 tmux attach-session -t "devnet"