#!/usr/bin/env bash # Arranca el nodo de Origin Chain en la rp1 si no está corriendo. Idempotente: lo llaman # cron @reboot y el vigilante cada 5 min. Sin root. # # Convivencia con la casa (la rp1 es también el runner de CI y el banco de Laurha): # - taskset -c 0-2: el nodo NUNCA toca el núcleo 3, que es el santuario de origin-banco. # - nice 10 + ionice best-effort 7: la CI tiene prioridad sobre el nodo. # - RPC sólo en 127.0.0.1: se entra por túnel SSH. P2P en 30333 para la LAN. # # Disco y memoria (medido el 2026-10-25, 23 h con los valores por defecto): 430 MB de WAL de # RocksDB retenidos para 15 MB de datos, y el RSS subiendo de 200 a 340 MB. RocksDB guarda el # WAL hasta que TODAS las columnas vacían su memtable, y con --db-cache por defecto (1 GiB) # eso tarda. --db-cache 128 lo acota. El log pasa de 7 líneas por bloque a ~2: se silencian # txpool, basic-authorship y aura (16 MB/día → unos 3). Va en modo append (>>) para que # medir.sh pueda rotarlo truncándolo sin dejar huecos. # # Cadena: `dev` (Alice, llaves de desarrollo PÚBLICAS). Es la testnet de la casa, no la # testnet pública: ningún valor real vive aquí. set -euo pipefail BASE="$HOME/origin-chain" BIN="$BASE/bin/origin-chain-node" PIDF="$BASE/nodo.pid" mkdir -p "$BASE/data" "$BASE/logs" # Una sola instancia a la vez. Desde que se espera a la red (más abajo, hasta 90 s), un tick del # vigilante (*/5) puede caer en medio de un @reboot. Sin el cerrojo arrancaban dos nodos: el segundo # muere por el lock de RocksDB, pero podía quedarse con nodo.pid, y entonces medir.sh medía un pid # muerto y «matar el pid» para volver atrás no paraba el nodo real (revisión de spec 19). exec 9>"$BASE/arrancar.lock" flock -n 9 || exit 0 # ¿Vive YA un nodo? Se mira la línea de comandos del pid, no sólo que exista: tras un reinicio, # nodo.pid es viejo y su número puede tenerlo otro proceso, y entonces `kill -0` acierta y el nodo # no arrancaría nunca. if [ -f "$PIDF" ] && tr '\0' ' ' <"/proc/$(cat "$PIDF")/cmdline" 2>/dev/null | grep -q "origin-chain-node run"; then exit 0 fi # Al encender la Pi, @reboot llega ANTES que la red: litep2p no levanta su transporte («transport # service closed» miles de veces) y el nodo se cierra solo en un segundo. Pasó en CADA reinicio # desde el 26-oct (medido en arranques.log y en los logs del nodo) y lo rescataba el vigilante # hasta 5 min después. Se espera a tener ruta por defecto, como mucho 90 s. Se lee # /proc/net/route y no `ip`, que con el PATH de cron puede no estar. espera=0 while [ $espera -lt 90 ] && ! awk 'NR > 1 && $2 == "00000000" { hay = 1 } END { exit !hay }' /proc/net/route; do sleep 1; espera=$((espera + 1)) done LOG="$BASE/logs/nodo-$(date +%Y%m%d-%H%M%S).log" # Un validador fuera de --dev exige una llave de red estable, y este CLI no trae `key`. Se # genera UNA vez (la vía 4 del propio nodo) y queda en el base-path; en los arranques # siguientes la bandera no se pasa, así que el peer id del bootnode no cambia nunca. LLAVE_RED="$BASE/data/chains/origin_chain_dev/network/secret_ed25519" EXTRA=() [ -f "$LLAVE_RED" ] || EXTRA=(--unsafe-force-node-key-generation) # El génesis lo fija casa.json (chain spec raw con el :code dentro), no el binario: el WASM no # es reproducible entre máquinas, y con `--chain dev` un binario nuevo crearía OTRO génesis # sobre los mismos datos. Sin casa.json (el primer arranque) se usa el `dev` embebido; después # se exporta con `bin/origin-chain-node build-spec --chain dev --raw > casa.json`. CADENA=dev [ -f "$BASE/casa.json" ] && CADENA="$BASE/casa.json" nohup taskset -c 0-2 nice -n 10 ionice -c2 -n7 "$BIN" run \ --chain "$CADENA" \ --validator --alice \ --name rp1-origin-casa \ --base-path "$BASE/data" \ --port 30333 \ --rpc-port 9944 --rpc-methods safe \ --no-telemetry --no-prometheus "${EXTRA[@]}" \ --db-cache 128 \ --log info,txpool=warn,basic-authorship=warn,sc_basic_authorship=warn,aura=warn \ >>"$LOG" 2>&1 9>&- & echo $! >"$PIDF" ln -sfn "$LOG" "$BASE/logs/actual.log" echo "$(date -Is) arrancado pid $(cat "$PIDF") log $LOG (red esperada ${espera}s)" >>"$BASE/logs/arranques.log"