Exploiter le relais

Pour votre relais nostrfy : démarrage et arrêt, journaux et statistiques, rechargement à chaud de la configuration, instances multiples et réglage à grande échelle.

Démarrage et arrêt

Démarrez le relais en démon d’arrière-plan :

sh
nostrfy --config nostrfy.toml start

=> nostrfy started (pid 12345)

Ou exécutez-le au premier plan dans le terminal :

sh
nostrfy --config nostrfy.toml start --foreground

Arrêter :

sh
nostrfy --config nostrfy.toml stop

Vérifiez qu’il est en marche :

sh
curl http://127.0.0.1:8080/health

=> {"status":"ok"}

Journaux et statistiques

Le démon écrit dans daemon.log_file. Lorsque le fichier dépasse max_log_size_bytes, il subit automatiquement une rotation (nostrfy.log.1, .2… jusqu’à max_log_files générations) :

sh
tail -f nostrfy.log

Le niveau de journalisation est contrôlé par la variable d’environnement RUST_LOG (par ex. RUST_LOG=debug).

Statistiques

Statistiques en direct depuis la CLI :

sh
nostrfy stats

Ou via HTTP :

sh
curl http://127.0.0.1:8080/relay/stats

Affiche les connexions, les événements acceptés/refusés, la taille de la base et plus.

Métriques Prometheus

sh
curl http://127.0.0.1:8080/metrics

Rechargement à chaud (SIGHUP)

Après avoir modifié le fichier de configuration, rechargez-le sans redémarrage :

sh
kill -HUP $(cat nostrfy.pid)
Appliqué au rechargementRedémarrage requis
Identité du relais, public_urlprivate_key
la plupart des limites, reject_ephemeral, enabled_git, enabled_nip78_authapi_host, metrics_enabled, réglages LiveKit
—enabled_nips / disabled_nips, server.host / port / ws_paths
—database.* (y compris search_index), blossom.*

Le journal avertit lorsqu’un réglage nécessitant un redémarrage a changé.

Exécuter plusieurs instances

nostrfy prend en charge plusieurs relais indépendants sur un même serveur (ports différents). Chaque instance a besoin de son propre server.port, [daemon] pid_file/log_file/stats_file (des valeurs partagées font que la seconde instance refuse de démarrer avec already running), database.path ainsi que (si utilisés) leurs propres api_host / blossom.host :

toml
[server]
port = 8080

[database]
path = "/var/lib/nostrfy-a"

[daemon]
pid_file = "/var/run/nostrfy-a.pid"
log_file = "/var/log/nostrfy-a.log"
stats_file = "/var/lib/nostrfy-a/stats.json"

[server]
port = 8081

[database]
path = "/var/lib/nostrfy-b"

[daemon]
pid_file = "/var/run/nostrfy-b.pid"
log_file = "/var/log/nostrfy-b.log"
stats_file = "/var/lib/nostrfy-b/stats.json"

Chaque instance est gérée avec sa propre configuration : nostrfy --config /etc/nostrfy/a.toml start et plus.

Déploiements à grande échelle

Le relais est conçu pour monter à des centaines de milliers de connexions sur un seul hôte — la diffusion live ne réveille que les abonnés pouvant correspondre et la mémoire par connexion reste faible. Pour atteindre le million, un réglage au niveau de l’hôte est nécessaire :

RéglageValeurRaison
ulimit -n / systemd LimitNOFILE≥ 2× les connexions visées (+1000)chaque connexion occupe un fd
net.core.somaxconn≥ 1024File d’accept en attente lors des pics de connexions
net.ipv4.tcp_fin_timeoutfaible (par ex. 10)Libère plus vite les sockets TIME_WAIT
vm.overcommit_memory1 ou 2La carte LMDB est une grande réservation virtuelle creuse

Sous FreeBSD, les paramètres correspondants sont kern.maxfiles / kern.maxfilesperproc plus ulimit -n ainsi que kern.ipc.somaxconn remplace net.core.somaxconn. La mémoire noyau par connexion est d’environ 80 KiB, l’espace utilisateur d’environ 10 KiB : un million de connexions demande donc environ 90 GiB de mémoire noyau + utilisateur en plus de la base.

Débit (événements par seconde)

L’écriture des événements est limitée par deux coûts : la vérification de signature Schnorr (environ 30 à 50 µs par événement) et le vidage disque synchrone effectué par l’écrivain LMDB après chaque lot de commits. Les deux se règlent dans le fichier nostrfy.toml :

RéglageRaison
database.disabled_fsync = trueCommit dans le cache de pages de l’OS (microsecondes) ; une coupure de courant ne perd que les écritures depuis le dernier vidage — commencez par là
Cœurs CPU ≥ 8 vCPULe chemin EVENT par lots vérifie les signatures en parallèle sur les cœurs
database.search_index = falseSupprime l’écriture de l’index de mots NIP-50 par événement pour les instances à forte écriture

La vérification parallèle des signatures vérifie toutes les signatures d’un lot en attente d’un coup, sur un pool de threads (plafonné à 8 ; les lots de moins de 16 événements sont vérifiés en ligne). Les contrôles peu coûteux passent toujours en premier, donc le texte de rejet est identique au chemin séquentiel — seul le travail Schnorr est réparti sur les cœurs. Une compilation mono-thread reste séquentielle.

Limites anti-abus fixes

Quelques limites strictes sont fixes (non configurables) pour que le relais reste réactif sous abus :

  • Un filtre contient au plus 512 entrées ids, authors ou kinds ; les valeurs de tags #... disposent d’un budget séparé de 512 valeurs. Les filtres plus grands sont refusés (CLOSED invalid: ...).
  • max_connections_per_sec_per_ip suit au plus 10 000 IP sources ; une fois plein, les IP inédites sont refusées (fail closed).
  • Les ids des filtres peuvent être des préfixes, mais seuls les id complets de 32 octets et les préfixes de longueur paire correspondent (les entrées impaires/vides sont ignorées en historique comme en diffusion live).
  • Les clés d’index trop longues (valeurs de tags, mots du contenu, tags d au-delà de la limite de taille de clé LMDB) sont ignorées à l’indexation ; l’événement est tout de même stocké.