This commit is contained in:
2026-07-23 16:37:12 +02:00
parent 99c345f2f2
commit 0da75c1311
2159 changed files with 230833 additions and 0 deletions

View File

@@ -0,0 +1,210 @@
<!-- file: docs/AGAVE_LOCAL_NODE.md -->
<!-- version: 3 -->
# Nœud Agave local expérimental
Ce document cadre le jalon `0.3.x`. L'objectif est de mesurer si un nœud Agave local non votant peut devenir une source temps réel utile avant de construire l'ingestion, le backfill et l'extracteur raw vers core en `0.4.x`.
## Positionnement
`khadhroony-bot2` ne doit pas embarquer un validateur. Le validateur reste un process externe démarré manuellement ou par script de développement.
```text
agave-validator local non votant
-> HTTP RPC local
-> WebSocket RPC local
-> demo_ws ou future démo Agave
-> mesures de capacité et de retard
-> décision pour l'ingestion 0.4.x
```
Le jalon `0.3.x` est une phase de recherche. Il ne doit pas écrire de raw de production, ne doit pas extraire vers core et ne doit pas déclencher d'achat/revente.
## Hypothèse à tester
Un nœud local Agave non votant avec ledger pruné pourrait permettre :
- `blockSubscribe` local avec transactions complètes ;
- moins de `getTransaction` temps réel ;
- moins de listeners par programme ;
- filtrage local par program id, logs, instructions, balances et discriminators ;
- usage des providers externes surtout pour backfill historique, réparation et `sendTransaction`.
Cette hypothèse doit être mesurée. Elle ne doit pas devenir une décision d'architecture sans chiffres locaux.
## Commande de départ
La commande exacte dépend de la version Agave installée, du snapshot disponible, des ports libres et des ressources locales. La commande de départ à documenter et ajuster est :
```bash
agave-validator \
--no-voting \
--full-rpc-api \
--enable-rpc-transaction-history \
--rpc-pubsub-enable-block-subscription \
--limit-ledger-size <N_SHREDS> \
--ledger ./data/agave-ledger \
--accounts ./data/agave-accounts \
--rpc-port 8899 \
--dynamic-port-range 8000-8020
```
`<N_SHREDS>` est une limite de shreds, pas une durée exacte ni un nombre exact de blocks. La fenêtre réellement conservée dépend du débit réseau, de la purge, des snapshots, de la vitesse disque et de l'état local du nœud.
## Préparation locale
Créer les dossiers explicitement pour éviter de mélanger le ledger expérimental avec d'autres données :
```bash
mkdir -p ./data/agave-ledger ./data/agave-accounts ./logs/agave_local_research
```
Avant chaque essai, noter :
```text
version agave-validator
commande exacte
valeur N_SHREDS
heure de lancement
état initial du dossier ledger
état initial du dossier accounts
profil de configuration utilisé
endpoint externe de référence
```
Ne pas supprimer automatiquement `./data/agave-ledger` ou `./data/agave-accounts` dans le projet. Toute purge doit rester une action manuelle et documentée dans le compte rendu d'essai.
## Profil de configuration
`config/example.config.json` contient le profil `agave_local_research`, non actif par défaut.
```text
HTTP local: http://127.0.0.1:8899
WS local: ws://127.0.0.1:8900
```
Pour l'utiliser, changer `active_profile` dans un fichier local non versionné ou lancer l'application avec `KB_CONFIG_PATH` pointant vers une copie locale.
Le profil expose les rôles suivants :
| Rôle | Usage |
|----------------------|-----------------------------------------------------------|
| `local_node_status` | santé, version et retard du nœud local |
| `http_queries` | lectures RPC légères locales |
| `http_heavy` | `getBlock`, `getTransaction`, `getProgramAccounts` locaux |
| `block_stream` | probe `blockSubscribe` local |
| `slot_notifications` | `slotSubscribe`, `slotsUpdatesSubscribe`, `rootSubscribe` |
| `logs_subscribe` | `logsSubscribe` par mention de programme |
| `program_subscribe` | `programSubscribe` par programme |
| `account_subscribe` | `accountSubscribe` par compte précis |
Le fallback externe est volontairement séparé. Il ne doit pas masquer un échec local pendant les mesures.
## Probes minimaux
Les probes `0.3.2` devront couvrir au minimum :
| Famille | Méthode | Résultat attendu |
|---------|-------------------------------------------------|--------------------------------------------------|
| HTTP | `getVersion` | version du nœud ou erreur explicite |
| HTTP | `getHealth` | état du nœud ou erreur explicite |
| HTTP | `getSlot` | slot local |
| HTTP | `getBlockHeight` | block height local |
| HTTP | `getMaxShredInsertSlot` | slot maximal de shred inséré |
| WS | `blockSubscribe` avec `transactionDetails=none` | `supported`, `unsupported`, `timeout` ou `error` |
| WS | `slotSubscribe` | subscription id puis notifications |
| WS | `slotsUpdatesSubscribe` | subscription id puis notifications |
| WS | `rootSubscribe` | subscription id puis notifications |
| WS | `logsSubscribe` `mentions` | subscription id ou refus provider |
| WS | `programSubscribe` | subscription id ou refus provider |
| WS | `accountSubscribe` | subscription id ou refus provider |
Le probe minimal `blockSubscribe` ne doit pas laisser un flux ouvert :
```text
1. ouvrir la WebSocket ;
2. envoyer blockSubscribe avec transactionDetails=none ;
3. attendre un subscription id ou une erreur ;
4. désabonner immédiatement ;
5. classer supported / unsupported / timeout / error ;
6. journaliser la réponse brute tronquée si nécessaire.
```
Paramètres de départ à tester dans `demo_ws` :
```text
role: block_stream
method: blockSubscribe
filterJson: "all"
configJson: {"commitment":"confirmed","encoding":"json","transactionDetails":"none","showRewards":false}
```
Si `"all"` est refusé par la version RPC testée, documenter l'erreur et tester ensuite un filtre plus ciblé par programme dans `0.3.4`.
## Mesures à collecter
| Mesure | Commande ou source indicative | Rôle |
|-----------------------------|----------------------------------------------|-----------------------------------|
| taille ledger | `du -sh ./data/agave-ledger` | calibrer `--limit-ledger-size` |
| taille accounts | `du -sh ./data/agave-accounts` | vérifier le coût disque |
| CPU | `pidstat`, `top`, `htop` | mesurer le coût du nœud local |
| RAM | `pidstat`, `free`, `ps` | vérifier la faisabilité locale |
| réseau RX/TX | `nload`, `iftop`, `/proc/net/dev` | mesurer le coût mainnet |
| slot local | `getSlot` local | vérifier l'avancement |
| slot externe | `getSlot` provider de référence | calculer le retard |
| lag slots | slot externe moins slot local | détecter un décrochage |
| lag secondes | lag slots multiplié par estimation slot time | estimer l'impact trading |
| débit WebSocket | compte notifications par seconde | comparer les modes live |
| taille moyenne notification | taille texte JSON ou bytes WS | dimensionner raw_ws_notifications |
| reconnects | logs `kb_app_demo.demo_ws` et nœud | détecter l'instabilité |
| erreurs provider ou Agave | logs et réponses JSON-RPC | classer les limites |
La mesure de lag secondes reste approximative tant que le slot time local n'est pas calculé sur fenêtre glissante. Le chiffre utile pour la décision reste le couple `lag slots` plus `lag secondes estimées`.
## Erreurs à documenter sans les masquer
| Catégorie | Exemples à noter |
|------------|---------------------------------------------------------------------------------------------|
| snapshot | téléchargement lent, snapshot incompatible, absence de snapshot |
| ledger | corruption, purge trop agressive, croissance disque excessive |
| accounts | croissance inattendue, I/O saturée, chemin invalide |
| ports | `8899` occupé, port WS indisponible, `dynamic-port-range` trop étroit |
| ressources | CPU saturé, RAM insuffisante, disque saturé, réseau insuffisant |
| retard | slot local qui n'avance plus, lag croissant, root très en retard |
| RPC | méthode non supportée, timeouts, erreurs JSON-RPC |
| WebSocket | connexion refusée, fermeture serveur, subscription refusée, notifications trop volumineuses |
Un essai qui échoue est exploitable s'il indique précisément la commande, le contexte, l'erreur et la ressource bloquante.
## Table de résultats à remplir
| Date | Agave | N_SHREDS | durée | ledger | accounts | CPU moy/max | RAM moy/max | RX/TX | slot local | slot réf. | lag slots | lag sec. | blockSubscribe none | remarques |
|-----------|-----------|-----------|-----------|-----------|-----------|-------------|-------------|-----------|------------|-----------|-----------|-----------|---------------------|-----------|
| À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir | À remplir |
## Critères de décision pour `0.4.x`
Le nœud local peut être retenu comme source live principale uniquement si les conditions suivantes sont mesurées :
- le slot local suit l'endpoint externe avec un retard stable et acceptable ;
- le ledger et les accounts restent soutenables sur le disque local ;
- `blockSubscribe` est supporté et stable avec au moins `transactionDetails=none` ;
- le mode `full` ou `signatures` ne bloque pas la WebView ni le process Rust lorsqu'il sera testé ;
- les reconnects et timeouts restent rares ou récupérables ;
- un fallback externe reste disponible pour backfill, réparation et envoi de transaction.
Si une de ces conditions échoue, `0.4.x` doit privilégier `slotSubscribe + getBlock`, les listeners ciblés ou une stratégie hybride, sans dépendance obligatoire à Agave local.
## Sortie attendue de `0.3.x`
La fin de `0.3.x` doit produire une décision documentée :
```text
source temps réel principale retenue
fallback temps réel retenu
politique raw_ws_notifications
faisabilité du nœud local
limites ressources observées
prochain design de l'ingestion 0.4.x
```