A very experimental PLC implementation which uses BFT consensus for decentralization
1#!/bin/sh
2
3# Default to 4 nodes if no argument provided
4NUM_NODES="${1:-4}"
5
6# Validate input
7if ! echo "$NUM_NODES" | grep -qE '^[0-9]+$'; then
8 echo "Error: Number of nodes must be a positive integer"
9 echo "Usage: $0 [number_of_nodes]"
10 echo "Example: $0 7"
11 exit 1
12fi
13
14if [ "$NUM_NODES" -lt 1 ]; then
15 echo "Error: Number of nodes must be at least 1"
16 exit 1
17fi
18
19echo "Starting testnet with $NUM_NODES nodes (preserving existing data)..."
20
21# Check if testnet directory exists and has the expected number of nodes
22if [ ! -d "testnet/node0" ]; then
23 echo "Error: No existing testnet found. Run ./startfresh-testnet.sh first to create the testnet."
24 exit 1
25fi
26
27# Count existing nodes
28existing_nodes=0
29for i in $(seq 0 99); do
30 if [ -d "testnet/node$i" ]; then
31 existing_nodes=$((existing_nodes + 1))
32 else
33 break
34 fi
35done
36
37if [ "$NUM_NODES" -gt "$existing_nodes" ]; then
38 echo "Error: Requested $NUM_NODES nodes but only $existing_nodes nodes exist in testnet/"
39 echo "Run ./startfresh-testnet.sh $NUM_NODES to create additional nodes."
40 exit 1
41fi
42
43echo "Found $existing_nodes existing nodes, starting first $NUM_NODES nodes..."
44
45# Check if binary exists, build if needed
46if [ ! -f "./didplcbft" ]; then
47 echo "Binary not found, building didplcbft..."
48 go build -trimpath
49fi
50
51# Array to store background process IDs
52pids=""
53
54# Cleanup function to kill all background processes
55cleanup() {
56 echo ""
57 echo "Shutting down all nodes..."
58
59 # Kill all background processes
60 for pid in $pids; do
61 if kill -0 "$pid" 2>/dev/null; then
62 echo " Stopping node process $pid..."
63 kill "$pid" 2>/dev/null
64 fi
65 done
66
67 # Clean up temporary fifo files
68 for i in $(seq 0 99); do
69 rm -f "/tmp/didplcbft-node$i-stdout" "/tmp/didplcbft-node$i-stderr" 2>/dev/null
70 done
71
72 # Wait for all processes to terminate
73 wait $pids 2>/dev/null
74
75 echo "All nodes stopped."
76 exit 0
77}
78
79# Set up signal traps
80trap cleanup INT TERM EXIT
81
82# Launch all nodes in parallel
83echo "Launching $NUM_NODES nodes in parallel..."
84
85for i in $(seq 0 $((NUM_NODES - 1))); do
86 if [ -d "testnet/node$i" ]; then
87 echo " Starting node$i..."
88 mkfifo "/tmp/didplcbft-node$i-stdout" 2>/dev/null || true
89 mkfifo "/tmp/didplcbft-node$i-stderr" 2>/dev/null || true
90
91 # Start sed processes to prefix output
92 sed "s/^/[node$i-stdout] /" < "/tmp/didplcbft-node$i-stdout" &
93 sed "s/^/[node$i-stderr] /" < "/tmp/didplcbft-node$i-stderr" &
94
95 # Start the didplcbft process with redirected output
96 ./didplcbft --data-dir "testnet/node$i" > "/tmp/didplcbft-node$i-stdout" 2> "/tmp/didplcbft-node$i-stderr" &
97 pid=$!
98 pids="$pids $pid"
99 echo " PID: $pid"
100 else
101 echo " Warning: node$i directory not found, skipping..."
102 fi
103done
104
105echo ""
106echo "All $NUM_NODES nodes are now running."
107echo "Press Ctrl+C to stop all nodes."
108echo ""
109
110# Wait for all background processes
111wait $pids
112
113# If we reach here, all processes have terminated normally
114echo "All nodes have terminated."