-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.cursorrules
More file actions
369 lines (309 loc) Β· 11.9 KB
/
Copy path.cursorrules
File metadata and controls
369 lines (309 loc) Β· 11.9 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
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
# Valops Project - Architectural Rules
## Core Principles
### Library Functions (`libs/*-lib.sh`)
- **Source-friendly design** - safe to source without side effects
- **NEVER use global variables** - only accept explicit arguments and use locals
- **NEVER provide defaults** - caller's responsibility to handle defaults
- **Pure functions** - side-effect free, predictable, testable
- **Explicit parameter documentation** - comment with parameter list
- **Parameter validation** - validate required parameters and fail fast
- **No executable code at file level** - only function definitions
- **Example:**
```bash
# Parameters: username data_dir rpc_bind_ip rpc_bind_port
update_validator_operator() {
local username="$1"
local data_dir="$2"
local rpc_bind_ip="$3"
local rpc_bind_port="$4"
# Validate required parameters
if [[ -z "$username" || -z "$data_dir" ]]; then
log_error "username and data_dir parameters are required"
return 1
fi
# ... no ${VAR:-default} patterns in library functions
}
```
### Environment Helper Functions (`libs/env-lib.sh`)
- **Pure computation functions** - return values via echo, no side effects
- **Configuration logic** - endpoint selection, path construction, etc.
- **Reusable across environments** - testnet, mainnet, devnet
- **Example:**
```bash
# Parameters: network mode
default_titan_endpoint() {
local network="$1"
local mode="$2"
case "$network" in
testnet) echo "https://titan-public-http.test.arch.network" ;;
esac
}
```
## Service-Specific Variable Naming Convention
**CRITICAL**: Multi-service environments MUST use service prefixes to avoid ambiguity:
### **Required Prefixes:**
- `ARCH_*` - Validator/Arch Network service variables
- `BITCOIN_*` - Bitcoin node service variables
- `TITAN_*` - Titan indexer service variables
### **Examples:**
```bash
# CORRECT - Clear service ownership
export ARCH_DATA_DIR="/validator/data"
export BITCOIN_DATA_DIR="/bitcoin/data"
export TITAN_DATA_DIR="/titan/data"
export ARCH_WEBSOCKET_ENABLED=true
export ARCH_WEBSOCKET_BIND_PORT=8081
export BITCOIN_RPC_BIND_PORT=8332
export TITAN_HTTP_BIND_PORT=3030
```
### **WRONG - Ambiguous variables:**
```bash
# NEVER DO THIS - Which service?
export DATA_DIR="/some/path" # Validator? Bitcoin? Titan?
export WEBSOCKET_ENABLED=true # Which websocket server?
export RPC_BIND_PORT=9002 # Which RPC endpoint?
```
### **Service Configuration Order:**
Environment files should configure services in dependency order:
1. **Bitcoin** (base layer)
2. **Titan** (depends on Bitcoin for indexing)
3. **Arch/Validator** (depends on both Bitcoin and Titan)
### **Network Configuration Consistency:**
**CRITICAL**: When running local infrastructure services, Bitcoin and Titan network modes MUST match:
```bash
# CORRECT - Network modes match
export BITCOIN_NETWORK_MODE=mainnet
export TITAN_NETWORK_MODE=mainnet
# WRONG - Network mismatch causes titan startup failure
export BITCOIN_NETWORK_MODE=mainnet
export TITAN_NETWORK_MODE=testnet # β MismatchedChain error
```
**Environment-specific patterns:**
- **testnet**: Bitcoin=mainnet, Titan=mainnet (Arch validator testnet runs on Bitcoin mainnet)
- **mainnet**: Bitcoin=mainnet, Titan=mainnet
- **devnet**: Bitcoin=regtest, Titan=regtest
### **Service Independence Principle:**
**CRITICAL**: Infrastructure service lifecycle is independent of application configuration:
- **`ARCH_TITAN_MODE`**: Only affects **validator connection** (local vs remote titan endpoint)
- **`titan-up`/`titan-down`**: **Infrastructure management** - operates independently of `ARCH_TITAN_MODE`
- **Validator**: Can run with `ARCH_TITAN_MODE=remote` while local titan is down
```bash
# Validator uses remote titan - local titan can be managed independently
export ARCH_TITAN_MODE=remote
export ARCH_TITAN_ENDPOINT=https://titan-public-http.test.arch.network
# These commands work regardless of ARCH_TITAN_MODE
titan-up # Starts local titan infrastructure
titan-down # Stops local titan infrastructure
```
**Key insight**: Distinguish between **infrastructure services** (bitcoin-up/titan-up) and **application configuration** (ARCH_* variables).
### Executable Scripts (`bin/*-up`, `bin/*-down`, etc.)
- **CRITICAL RULE**: Only `main()` function accesses global variables - NO EXCEPTIONS
- **All other functions**: Must use explicit parameters only, never access globals
- **Usage function**: REQUIRED for all scripts, called from help flag and error conditions
- **Environment validation**: Done in `main()` only, not delegated to other functions
- **Parameter passing**: `main()` reads globals, passes explicit parameters to all functions
- **Example:**
```bash
# Usage function - REQUIRED
usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS]
Description of what this script does.
Options:
-h, --help Show this help message
Environment Variables (set by .envrc):
REQUIRED_VAR Description
EOF
}
# Pure function - NO global access
ensure_service_infrastructure() {
local service_user="$1"
local service_config="$2"
# Validate required parameters
if [[ -z "$service_user" ]]; then
log_error "service_user parameter is required"
return 1
fi
# ... implementation using only local vars and parameters
}
# ONLY main() accesses globals
main() {
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h | --help)
usage
exit 0
;;
*)
log_error "Unknown option: $1"
usage # Always call usage on error
exit 1
;;
esac
done
# Validate required environment variables
local missing_vars=()
[[ -z "${REQUIRED_VAR:-}" ]] && missing_vars+=("REQUIRED_VAR")
if [[ ${#missing_vars[@]} -gt 0 ]]; then
log_error "Missing required environment variables: ${missing_vars[*]}"
usage # Always call usage on error
exit 1
fi
# Call functions with explicit parameters
ensure_service_infrastructure "$REQUIRED_VAR" "$OTHER_VAR"
}
```
### Code Modification Rules
- **WHEN EDITING EXISTING CODE**: Upgrade to these patterns during the edit
- **NO MIXED PATTERNS**: Don't leave some functions using globals while others use parameters
- **REFACTOR INCREMENTALLY**: When touching a function, upgrade it to pure parameter-based design
- **REMOVE DEAD CODE**: Delete unused flags, variables, or functions during edits
- **USAGE FUNCTIONS**: Add usage() function if script doesn't have one
### Configuration Scripts (`.envrc` files)
- **Driver for defaults** - primary place where sensible defaults are set
- **Environment-specific values** - different per chain/network
- **Use helper functions** (e.g. `select_by_mode`) for conditional logic
- **Example:**
```bash
# Set defaults at configuration level
export DATA_DIR="${DATA_DIR:-/home/$VALIDATOR_USER/data/.arch_data}"
export RPC_BIND_PORT="${RPC_BIND_PORT:-9002}"
export WEBSOCKET_ENABLED="${WEBSOCKET_ENABLED:-false}"
```
### User Override System (`.env` files - git ignored)
- **Final override layer** - user-specific customizations
- **Never committed to git** - local development/deployment tweaks
- **Simple key=value format**
- **Example:**
```bash
WEBSOCKET_ENABLED=true
RPC_BIND_PORT=9003
```
## Layered Configuration System
```
.env (git ignored) β User overrides (highest priority)
β
.envrc (tracked) β Defaults and environment logic
β
executable scripts (bin/) β Environment reading + validation (main() only)
β
library functions (libs/) β Source-friendly, pure functions with explicit args
```
## Directory Structure
```
valops/
βββ .envrc # Project-wide PATH and env-lib sourcing
βββ .env # User overrides (git ignored)
βββ bin/ # Executable scripts
β βββ validator-up # Infrastructure management
β βββ validator-down # Service teardown
β βββ validator-init # Identity creation
β βββ backup-all # Backup utilities
βββ libs/ # Source-friendly library functions only
β βββ validator-lib.sh # Validator management functions
β βββ env-lib.sh # Environment helper functions
β βββ lib.sh # Common utilities
βββ validators/ # Environment-specific configs
βββ testnet/
βββ .envrc # Testnet defaults and overrides
```
## Anti-Patterns to Avoid
### β Globals in Libraries
```bash
# WRONG - library using globals
function bad_library() {
local port="${RPC_BIND_PORT:-9002}" # NO!
}
```
### β Globals in Non-Main Functions
```bash
# WRONG - function other than main() accessing globals
ensure_service_running() {
local user="$SERVICE_USER" # NO! Only main() can do this
}
```
### β Missing Usage Functions
```bash
# WRONG - no usage function, hard to debug errors
if [[ -z "$REQUIRED_VAR" ]]; then
log_error "REQUIRED_VAR is required" # NO! Should call usage()
exit 1
fi
```
### β Defaults in Executables
```bash
# WRONG - executable providing defaults
data_dir="${DATA_DIR:-/default/path}" # NO!
```
### β Complex Logic in Executables
```bash
# WRONG - complex conditional logic in scripts
if [[ "$NETWORK" == "testnet" ]]; then
endpoint="https://test.example.com"
else
endpoint="https://prod.example.com"
fi
```
## Correct Patterns
### β
Library Functions
```bash
# Parameters: username network_mode endpoint
setup_network() {
local username="$1"
local network_mode="$2"
local endpoint="$3"
# Validate required parameters
if [[ -z "$username" || -z "$network_mode" ]]; then
log_error "username and network_mode parameters are required"
return 1
fi
# Pure function - no globals, explicit params only
}
```
### β
Executable Scripts
```bash
# ONLY main() accesses globals
main() {
# Parse args, validate environment
local username="$VALIDATOR_USER"
local network_mode="$NETWORK_MODE"
local endpoint="$TITAN_ENDPOINT"
# Validate required
local missing_vars=()
[[ -z "$username" ]] && missing_vars+=("VALIDATOR_USER")
if [[ ${#missing_vars[@]} -gt 0 ]]; then
log_error "Missing required environment variables: ${missing_vars[*]}"
usage
exit 1
fi
# Call library with explicit parameters
setup_network "$username" "$network_mode" "$endpoint"
}
```
### β
Configuration (.envrc)
```bash
# Provide sensible defaults
export VALIDATOR_USER="${VALIDATOR_USER:-testnet-validator}"
export NETWORK_MODE="${NETWORK_MODE:-testnet}"
export ARCH_TITAN_ENDPOINT="${ARCH_TITAN_ENDPOINT:-$(select_by_mode $ARCH_TITAN_MODE \
"http://127.0.0.1:3030" \
"https://titan-public-http.test.arch.network")}"
```
## Benefits
- **Predictable**: Clear data flow and responsibility boundaries
- **Testable**: Pure library functions easy to unit test
- **Maintainable**: Changes propagate correctly through layers
- **Flexible**: Users can override at appropriate level
- **Debuggable**: Easy to trace where values come from
## Backup Safety Rule
**π¨ CRITICAL SAFETY REQUIREMENT**: All init and startup scripts (`validator-init`, `validator-up`, etc.) MUST include auto-backup at the end using this exact pattern:
```bash
# Auto-backup after initialization/successful start
"$PROJECT_ROOT/bin/backup-all"
```
**BACKUP FAILURES ARE NEVER ACCEPTABLE** - they indicate critical safety issues that must be fixed immediately. The backup must:
- **NOT be silent** - should fail loudly if backup fails
- **Use PROJECT_ROOT** - `$PROJECT_ROOT/bin/backup-all` for consistency
- **Block script completion** - script fails if backup fails
- **Always run** - even for minor operations, safety first