-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode.sh
More file actions
executable file
·340 lines (291 loc) · 11.4 KB
/
Copy pathnode.sh
File metadata and controls
executable file
·340 lines (291 loc) · 11.4 KB
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
#!/bin/bash
# Ethereum Node Management Script
# Works on both Linux and macOS
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored messages
print_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Load environment files
load_env_files() {
print_info "Loading environment files..."
# Source main .env file
if [ -f ".env" ]; then
set -a
source .env
set +a
else
cp default.env .env
set -a
source .env
set +a
print_warning "Created .env from default.env"
fi
# Source all environment files
for file in ./environments/.env.*; do
if [ -f "$file" ]; then
set -a
source "$file"
set +a
fi
done
print_info "Environment files loaded successfully"
}
# Build docker-compose command with appropriate files
build_compose_command() {
local compose_files="-f docker-compose.base.yml"
local services_count=0
print_info "Building service configuration..." >&2
# Execution clients (mutually exclusive)
if [ "${START_NETHERMIND}" = "true" ]; then
compose_files="$compose_files -f execution/nethermind/docker-compose.yml"
print_info " ✓ Nethermind execution client" >&2
((services_count++))
fi
if [ "${START_BESU}" = "true" ]; then
compose_files="$compose_files -f execution/besu/docker-compose.yml"
print_info " ✓ Besu execution client" >&2
((services_count++))
fi
if [ "${START_GETH}" = "true" ]; then
compose_files="$compose_files -f execution/geth/docker-compose.yml"
print_info " ✓ Geth execution client" >&2
((services_count++))
fi
if [ "${START_RETH}" = "true" ]; then
compose_files="$compose_files -f execution/reth/docker-compose.yml"
print_info " ✓ Reth execution client" >&2
((services_count++))
fi
if [ "${START_ERIGON}" = "true" ]; then
compose_files="$compose_files -f execution/erigon/docker-compose.yml"
print_info " ✓ Erigon execution client" >&2
((services_count++))
fi
# Consensus clients
if [ "${START_NIMBUS_CC_VC}" = "true" ]; then
compose_files="$compose_files -f consensus/nimbus/docker-compose.yml"
print_info " ✓ Nimbus consensus + validator" >&2
((services_count++))
fi
if [ "${START_LIGHTHOUSE_CC}" = "true" ]; then
compose_files="$compose_files -f consensus/lighthouse/docker-compose.yml"
print_info " ✓ Lighthouse consensus client" >&2
((services_count++))
fi
if [ "${START_LIGHTHOUSE_VC}" = "true" ]; then
compose_files="$compose_files -f consensus/lighthouse/docker-compose.validator.yml"
print_info " ✓ Lighthouse validator client" >&2
((services_count++))
fi
# Additional services
if [ "${START_MEV_BOOST}" = "true" ]; then
compose_files="$compose_files -f mev-boost/docker-compose.yml"
print_info " ✓ MEV-Boost" >&2
((services_count++))
fi
if [ "${START_EXECBACKUP}" = "true" ]; then
compose_files="$compose_files -f execbackup/docker-compose.yml"
print_info " ✓ Execution backup (failover)" >&2
((services_count++))
fi
if [ "${START_NGINX_PROXY}" = "true" ]; then
compose_files="$compose_files -f docker-compose.nginx.yml"
print_info " ✓ Nginx proxy" >&2
((services_count++))
# Check if VIRTUAL_HOST is configured for any enabled service
check_nginx_virtual_hosts
fi
if [ "${START_SOCAT}" = "true" ]; then
compose_files="$compose_files -f socat/docker-compose.yml"
print_info " ✓ Socat interceptor" >&2
((services_count++))
fi
if [ "${START_CLEF}" = "true" ]; then
compose_files="$compose_files -f execution/geth/docker-compose.clef.yml"
print_info " ✓ Clef signer" >&2
((services_count++))
fi
if [ $services_count -eq 0 ]; then
print_error "No services selected! Please configure your .env file." >&2
exit 1
fi
echo "$compose_files"
}
# Check if nginx-proxy VIRTUAL_HOST variables are configured
check_nginx_virtual_hosts() {
local has_execution=false
local has_consensus=false
local warnings=()
# Check if any execution client is enabled
if [ "${START_NETHERMIND}" = "true" ] || [ "${START_BESU}" = "true" ] || \
[ "${START_GETH}" = "true" ] || [ "${START_RETH}" = "true" ] || \
[ "${START_ERIGON}" = "true" ]; then
has_execution=true
fi
# Check if any consensus client is enabled
if [ "${START_LIGHTHOUSE_CC}" = "true" ] || [ "${START_NIMBUS_CC_VC}" = "true" ]; then
has_consensus=true
fi
# Load environment files to check VIRTUAL_HOST values
if [ "$has_execution" = true ] && [ -f "./environments/.env.execution" ]; then
local exec_virtual_host=$(grep "^VIRTUAL_HOST=" ./environments/.env.execution | cut -d'=' -f2)
if [ -z "$exec_virtual_host" ]; then
warnings+=(" ⚠️ VIRTUAL_HOST not set in environments/.env.execution")
fi
fi
if [ "$has_consensus" = true ] && [ -f "./environments/.env.consensus" ]; then
local consensus_virtual_host=$(grep "^VIRTUAL_HOST=" ./environments/.env.consensus | cut -d'=' -f2)
if [ -z "$consensus_virtual_host" ]; then
warnings+=(" ⚠️ VIRTUAL_HOST not set in environments/.env.consensus")
fi
fi
# Display warnings if any
if [ ${#warnings[@]} -gt 0 ]; then
print_warning "Nginx-proxy is enabled but VIRTUAL_HOST not configured:" >&2
for warning in "${warnings[@]}"; do
echo "$warning" >&2
done
print_info "Nginx-proxy will run but won't route traffic without VIRTUAL_HOST set." >&2
print_info "See 'Nginx Reverse Proxy' section in README.md for setup." >&2
fi
}
# Check if JWT secret exists, create if not
check_jwt_secret() {
if [ ! -f "./secrets/jwt.hex" ]; then
print_info "Generating JWT secret..."
mkdir -p ./secrets
# Generate random hex string (32 bytes = 64 hex chars)
if command -v openssl &> /dev/null; then
openssl rand -hex 32 > ./secrets/jwt.hex
else
# Fallback for systems without openssl
if command -v xxd &> /dev/null; then
head -c 32 /dev/urandom | xxd -p -c 32 > ./secrets/jwt.hex
else
print_error "Neither openssl nor xxd found. Please install one to generate JWT secret."
exit 1
fi
fi
print_info "JWT secret created at ./secrets/jwt.hex"
fi
}
# Validate Erigon internal consensus configuration
validate_erigon_internal_consensus() {
# Check if Erigon is enabled and internal consensus is enabled
if [ "${START_ERIGON}" = "true" ] && [ "${ENABLE_INTERNAL_CONSENSUS_CLI}" = "true" ]; then
# Check if any consensus client is enabled
if [ "${START_NIMBUS_CC_VC}" = "true" ]; then
print_error "ERROR: Cannot run Nimbus consensus when Erigon internal consensus is enabled"
print_error "Erigon's internal consensus replaces the need for a separate consensus client"
print_error "Either:"
print_error " - Set ENABLE_INTERNAL_CONSENSUS_CLI=false in environments/.env.execution"
print_error " - Set START_NIMBUS_CC_VC=false in .env"
exit 1
fi
if [ "${START_LIGHTHOUSE_CC}" = "true" ]; then
print_error "ERROR: Cannot run Lighthouse consensus when Erigon internal consensus is enabled"
print_error "Erigon's internal consensus replaces the need for a separate consensus client"
print_error "You can still run Lighthouse validator (START_LIGHTHOUSE_VC=true) alongside Erigon"
print_error "Either:"
print_error " - Set ENABLE_INTERNAL_CONSENSUS_CLI=false in environments/.env.execution"
print_error " - Set START_LIGHTHOUSE_CC=false in .env"
exit 1
fi
# Inform user about validator compatibility
if [ "${START_LIGHTHOUSE_VC}" = "true" ]; then
print_info "✓ Running Lighthouse validator with Erigon internal consensus" >&2
else
print_info "✓ Running Erigon with internal consensus (no external consensus client needed)" >&2
fi
fi
}
# Main execution
main() {
print_info "=== Ethereum Node Startup Script ==="
print_info "Platform: $(uname -s)"
# Check if docker compose is available
if ! command -v docker &> /dev/null; then
print_error "Docker is not installed or not in PATH"
exit 1
fi
# Check for docker compose
if ! docker compose version &> /dev/null; then
print_error "Docker Compose is not available. Please install Docker Compose"
exit 1
fi
# Load environment variables
load_env_files
# Validate Erigon internal consensus configuration
validate_erigon_internal_consensus
# Check/create JWT secret
check_jwt_secret
# Build compose command
compose_files=$(build_compose_command)
# Parse command line arguments
case "${1:-up}" in
up|start)
print_info "Pulling latest Docker images..."
docker compose $compose_files pull
print_info "Starting services..."
docker compose $compose_files up -d --build
print_info "Services started successfully!"
print_info "Use './node.sh logs' to view logs"
print_info "Use './node.sh stop' to stop services"
;;
down|stop)
print_info "Stopping services..."
docker compose $compose_files down --remove-orphans
print_info "Services stopped"
;;
restart)
print_info "Restarting services..."
docker compose $compose_files down --remove-orphans
docker compose $compose_files up -d --build
print_info "Services restarted"
;;
logs)
docker compose $compose_files logs -f "${@:2}"
;;
ps|status)
docker compose $compose_files ps
;;
pull)
print_info "Pulling latest images..."
docker compose $compose_files pull
;;
config)
print_info "Generating merged configuration..."
docker compose $compose_files config
;;
*)
echo "Usage: $0 {up|start|down|stop|restart|logs|ps|status|pull|config}"
echo ""
echo "Commands:"
echo " up/start - Start services (default)"
echo " down/stop - Stop services"
echo " restart - Restart all services"
echo " logs - Follow logs (add service name to filter)"
echo " ps/status - Show running services"
echo " pull - Pull latest Docker images"
echo " config - Show merged docker-compose configuration"
echo ""
echo "Environment variables:"
echo " Edit .env file to configure which services to start"
exit 1
;;
esac
}
# Run main function
main "$@"