44
55# Like devnet.sh, but with these changes that stabilize the network topology:
66#
7- # * Only asks for the number N of validators, not the number of clients.
8- # Makes the same number of clients as validators, to reflect
9- # the concept that each validator has has a dedicated core client.
10- # (Currently we are waiting for more information about how mainnet validators
11- # set up their trusted peers; this script can then be updated to match.)
7+ # * Asks for the number N of validators, not the number of clients.
8+ # Asks how many core clients each validator should have.
9+ # Makes the appropriate number of clients, to reflect
10+ # the concept that each validator has 1 or 2 dedicated core clients.
1211# * For the Gateway (communication for BFT consensus)
1312# sets --validators starting up each validator to all the other validators
1413# (devnet.sh ends up setting it only to the first two validators).
1514# * For the Router (p2p communication), sets --peers (the trusted peers)
1615# directly, rather than allowing them to be set by parse_development(),
17- # * Each validator has one trusted peer : its core client .
16+ # * Each validator has 1 or 2 trusted peers : its core clients .
1817# No longer allow validators to accept external peer connections
1918# (removed the "--allow-external-peers" flag).
20- # * Each client has N trusted peers: its one trusted validator
21- # and the N-1 other clients.
19+ # * Each client has either
20+ # N trusted peers (when there is 1 core client per validator)
21+ # or 2N trusted peers (when there are 2 core clients per validator).
22+ # In the first case, the client's trusted peers are its validator and N-1 other clients.
23+ # In the second case, the client's trusted peers are its validator and 2N-1 other clients.
2224
2325if [[ -n " $TMUX " ]]; then
2426 echo " Detected nested tmux session. Try again after unsetting \$ TMUX, e.g., using \` unset TMUX\` in bash."
2931read -p " Enter the total number of validators (default: 4): " total_validators
3032total_validators=${total_validators:- 4}
3133
32- # Each validator trusts one core client.
33- total_clients=${total_validators}
34+ # Validate that total_validators is a positive integer
35+ if ! [[ " $total_validators " =~ ^[1-9][0-9]* $ ]]; then
36+ echo " Error: Number of validators must be a positive integer"
37+ exit 1
38+ fi
3439
3540# Read the network ID from user or use a default value of 1
3641read -p " Enter the network ID (mainnet = 0, testnet = 1, canary = 2) (default: 1): " network_id
3742network_id=${network_id:- 1}
3843
44+ # Validate that network_id is 0, 1, or 2
45+ if ! [[ " $network_id " =~ ^[012]$ ]]; then
46+ echo " Error: Network ID must be 0 (mainnet), 1 (testnet), or 2 (canary)"
47+ exit 1
48+ fi
49+
50+ # Read the number of core clients per validator from user or use a default value of 2
51+ read -p " Enter the number of core clients for each validator (1 or 2; default: 2): " core_clients_per_validator
52+ core_clients_per_validator=${core_clients_per_validator:- 2}
53+
54+ # Validate that core_clients_per_validator is either 1 or 2
55+ if [[ " $core_clients_per_validator " != " 1" && " $core_clients_per_validator " != " 2" ]]; then
56+ echo " Error: Number of core clients per validator must be 1 or 2"
57+ exit 1
58+ fi
59+
60+ # The total number of clients is the number of validators times the number of core clients per validator.
61+ total_clients=$(( total_validators * core_clients_per_validator))
62+
3963# Ask the user if they want to run 'cargo install --locked --path .' or use a pre-installed binary
4064read -p " Do you want to run 'cargo install --locked --path .' to build the binary? (y/n, default: y): " build_binary
4165build_binary=${build_binary:- y}
@@ -111,14 +135,9 @@ for validator_index in "${validator_indices[@]}"; do
111135 name=" validator-$validator_index "
112136 log_file=" $log_dir /$name .log"
113137 window_index=$(( validator_index + index_offset))
114- metrics_flag= " "
138+ metrics_port= $(( validator_index + 9000 ))
115139
116- if [ " $validator_index " -eq 0 ]; then
117- # Enable metrics only for the first validator.
118- metrics_flag=" --metrics"
119- # We don't need to create a window for the first validator because the tmux
120- # session already starts with one window.
121- else
140+ if [ " $validator_index " -ne 0 ]; then
122141 # Create a new window with a unique name
123142 tmux new-window -t " devnet:$window_index " -n $name
124143 fi
@@ -135,31 +154,43 @@ for validator_index in "${validator_indices[@]}"; do
135154 fi
136155 done
137156
138- # Create the list of peers (i.e., trusted peers) for the validator at the_validator_index
139- # It is the corresponding client now.
140- # I.e., validators 0,1,2,3 each has one trusted peer which is the client at ports 4130 + num_validators + 0,1,2,3, respectively
141- validator_trusted_peers=" 127.0.0.1:$(( 4130 + total_validators + validator_index)) " ;
157+ # Create the list of peers (i.e., trusted peers) for the validator at validator_index.
158+ # Each validator has 1 or 2 trusted peers: its core clients
159+ if [ " $core_clients_per_validator " -eq 1 ]; then
160+ # Each validator has 1 trusted peer: its core client
161+ client_offset=$(( validator_index * core_clients_per_validator))
162+ validator_trusted_peers=" 127.0.0.1:$(( 4130 + total_validators + client_offset)) "
163+ else
164+ # Each validator has 2 trusted peers: its two core clients
165+ client_offset_1=$(( validator_index * core_clients_per_validator))
166+ client_offset_2=$(( validator_index * core_clients_per_validator + 1 ))
167+ validator_trusted_peers=" 127.0.0.1:$(( 4130 + total_validators + client_offset_1 )) ,127.0.0.1:$(( 4130 + total_validators + client_offset_2 )) "
168+ fi
142169
143170 # Send the command to start the validator to the new window and capture output to the log file
144- tmux send-keys -t " devnet:$window_index " " snarkos start --nodisplay --network $network_id --dev $validator_index --dev-num-validators $total_validators --validator --validators $trusted_validators --peers $validator_trusted_peers --logfile $log_file --verbosity $verbosity $metrics_flag " C-m
171+ tmux send-keys -t " devnet:$window_index " " snarkos start --nodisplay --network $network_id --dev $validator_index --dev-num-validators $total_validators --validator --validators $trusted_validators --peers $validator_trusted_peers --logfile $log_file --verbosity $verbosity --metrics --metrics-ip=0.0.0.0: $metrics_port " C-m
145172done
146173
147174# Define a function that generates the string to be passed as --peers when starting a client node.
148175# The trusted peers consist of the one paired validator plus all the other clients.
149- # The string looks like "vvv${i },ccc0,ccc1,...,ccc${n}"
176+ # The string looks like "vvv${v },ccc0,ccc1,...,ccc${n}"
150177# excluding ccc${i} from the list,
151- # where vvv${i } is "127.0.0.1:$((4130 + i ))"
178+ # where vvv${v } is "127.0.0.1:$((4130 + (i / core_clients_per_validator) ))"
152179# and ccc${i} is "127.0.0.1:$((4130 + total_validators + i))"
153180client_trusted_peers () {
154- # n is the number of validators (= number of clients)
181+ # n is the number of validators
155182 # i is the index of the client for which we want a trusted peers list
156183 local n=$1
157184 local i=$2
158185
159- local result=" 127.0.0.1:$(( 4130 + i)) "
186+ # Calculate which validator this client belongs to
187+ local validator_index=$(( i / core_clients_per_validator))
188+
189+ # Start with the client's validator as the first trusted peer.
190+ local result=" 127.0.0.1:$(( 4130 + validator_index)) "
160191
161- # Appends all ccc{number} from 0 to n-1, except ccc${i}
162- for (( j= 0 ; j< n ; j++ )) ; do
192+ # Add all other clients as trusted peers
193+ for (( j= 0 ; j< total_clients ; j++ )) ; do
163194 if [ $j -ne $i ]; then
164195 result=" ${result} ,127.0.0.1:$(( 4130 + total_validators + j)) "
165196 fi
@@ -168,25 +199,23 @@ client_trusted_peers() {
168199 echo " $result "
169200}
170201
171- if [ " $total_clients " -ne 0 ]; then
172- # Generate client indices from 0 to (total_clients - 1)
173- client_indices=($( seq 0 $(( total_clients - 1 )) ) )
202+ # Generate client indices from 0 to (total_clients - 1)
203+ client_indices=($( seq 0 $(( total_clients - 1 )) ) )
174204
175- # Loop through the list of client indices and create a new window for each
176- for client_index in " ${client_indices[@]} " ; do
177- # Generate a unique and incrementing log file name based on the client index
178- name=" client-$client_index "
179- log_file=" $log_dir /$name .log"
205+ # Loop through the list of client indices and create a new window for each
206+ for client_index in " ${client_indices[@]} " ; do
207+ # Generate a unique and incrementing log file name based on the client index
208+ name=" client-$client_index "
209+ log_file=" $log_dir /$name .log"
180210
181- window_index=$(( client_index + total_validators + index_offset))
211+ window_index=$(( client_index + total_validators + index_offset))
182212
183- # Create a new window with a unique name
184- tmux new-window -t " devnet:$window_index " -n $name
213+ # Create a new window with a unique name
214+ tmux new-window -t " devnet:$window_index " -n $name
185215
186- # Send the command to start the client to the new window and capture output to the log file
187- tmux send-keys -t " devnet:$window_index " " snarkos start --nodisplay --network $network_id --dev $(( total_validators + client_index)) --dev-num-validators $total_validators --client --peers $( client_trusted_peers $total_validators $client_index ) --logfile $log_file --verbosity $verbosity " C-m
188- done
189- fi
216+ # Send the command to start the client to the new window and capture output to the log file
217+ tmux send-keys -t " devnet:$window_index " " snarkos start --nodisplay --network $network_id --dev $(( total_validators + client_index)) --dev-num-validators $total_validators --client --peers $( client_trusted_peers $total_validators $client_index ) --logfile $log_file --verbosity $verbosity " C-m
218+ done
190219
191220# Attach to the tmux session to view and interact with the windows
192221tmux attach-session -t " devnet"
0 commit comments