148 lines
6.2 KiB
Markdown
148 lines
6.2 KiB
Markdown
<!-- file: docs/RAW_STORE.md -->
|
||
<!-- version: 6 -->
|
||
|
||
# Store transactionnel Solana canonique
|
||
|
||
## Historique
|
||
|
||
`0.2.3` a créé deux tables minimales :
|
||
|
||
```text
|
||
kb_sol_raw_rpc_transactions
|
||
kb_sol_raw_ws_notifications
|
||
```
|
||
|
||
Ces tables restent un jalon historique validé dans `CHANGELOG.md`. La transition a été appliquée et contrôlée sur PostgreSQL réel pendant `0.3.1`.
|
||
|
||
Le modèle actif est :
|
||
|
||
```text
|
||
kb_sol_raw_transactions
|
||
kb_sol_obs_transaction_observations
|
||
```
|
||
|
||
## Objectif cible
|
||
|
||
Le store principal conserve une transaction Solana source-indépendante par signature. Les sources HTTP, WebSocket Helius et Yellowstone gRPC ne doivent pas produire plusieurs copies complètes du même contenu.
|
||
|
||
```text
|
||
source provider
|
||
-> normalisation canonique
|
||
-> transaction unique
|
||
-> observations multiples
|
||
```
|
||
|
||
## Table `kb_sol_raw_transactions`
|
||
|
||
Rôle : stocker la représentation canonique rejouable de la transaction et de ses metadata.
|
||
|
||
Colonnes principales visées :
|
||
|
||
| Colonne | Rôle |
|
||
|----------------------------|-----------------------------------------|
|
||
| `id` | clé primaire technique |
|
||
| `signature` | signature Solana unique |
|
||
| `slot` | slot de la transaction |
|
||
| `canonical_format_version` | version du contrat canonique |
|
||
| `canonical_json` | transaction et metadata normalisées |
|
||
| `canonical_json_hash` | hash déterministe du document canonique |
|
||
| `retention_state` | état de rétention |
|
||
| `processing_state` | état d’extraction et de traitement |
|
||
| `lifecycle_reason` | raison technique optionnelle |
|
||
| `created_at` | première insertion |
|
||
| `updated_at` | dernière évolution autorisée |
|
||
|
||
Le contenu canonique ne contient pas de nom de fournisseur, endpoint, subscription id ou format de transport.
|
||
|
||
`kb_model::CanonicalTransaction` fournit la sérialisation déterministe et le hash SHA-256. `kb_store_core::RawTransactionInsert::from_canonical` construit le DTO de persistance avec la signature primaire, le slot, `canonical_format_version`, `canonical_json` et `canonical_json_hash`. Le transport RPC ne dépend donc pas du backend PostgreSQL.
|
||
|
||
## Table `kb_sol_obs_transaction_observations`
|
||
|
||
Rôle : enregistrer chaque détection ou acquisition d’une signature sans recopier le payload complet.
|
||
|
||
Colonnes principales visées :
|
||
|
||
| Colonne | Rôle |
|
||
|-----------------------|-------------------------------------------------------|
|
||
| `id` | clé primaire technique |
|
||
| `observation_key` | clé idempotente de l’observation |
|
||
| `raw_transaction_id` | lien optionnel vers `kb_sol_raw_transactions` |
|
||
| `signature` | signature détectée ou reçue |
|
||
| `slot` | slot quand connu |
|
||
| `provider` | fournisseur |
|
||
| `endpoint_code` | endpoint de configuration |
|
||
| `protocol` | protocole de transport |
|
||
| `acquisition_method` | méthode ou type de stream |
|
||
| `origin` | `live`, `backfill`, `replay`, `repair` ou `migration` |
|
||
| `commitment` | commitment demandé ou reçu |
|
||
| `capture_session_id` | session de mesure ou d’ingestion |
|
||
| `filter_code` | filtre logique utilisé |
|
||
| `detected_at` | premier signal reçu |
|
||
| `received_at` | transaction complète reçue |
|
||
| `normalized_at` | fin de normalisation |
|
||
| `persisted_at` | fin de persistance |
|
||
| `payload_size_bytes` | taille du message source |
|
||
| `source_payload_hash` | hash optionnel du message source |
|
||
| `status` | résultat technique |
|
||
| `error_code` | erreur normalisée optionnelle |
|
||
| `error_message` | message de diagnostic optionnel |
|
||
|
||
Cette table ne possède pas de `raw_json`, de `canonical_json` ni de payload Protobuf complet.
|
||
|
||
## Notifications WebSocket
|
||
|
||
`kb_sol_raw_ws_notifications` n’est plus conservée comme cible durable.
|
||
|
||
Pour `logsSubscribe` :
|
||
|
||
1. recevoir la signature et le slot ;
|
||
2. mémoriser temporairement le timestamp de détection ;
|
||
3. hydrater par `getTransaction` si nécessaire ;
|
||
4. écrire la transaction canonique ;
|
||
5. écrire une observation avec `detected_at`, `received_at` et le statut d’hydratation.
|
||
|
||
Les payloads complets de notifications peuvent être exportés temporairement pour un benchmark borné, mais ils ne doivent pas être dupliqués en PostgreSQL.
|
||
|
||
## Fusion par signature
|
||
|
||
La signature est la clé d’unicité de la transaction canonique.
|
||
|
||
- hash identique : conserver la ligne et ajouter une observation ;
|
||
- metadata plus complètes : appliquer un enrichissement déterministe ;
|
||
- différence incompatible : enregistrer un conflit et ne pas écraser silencieusement ;
|
||
- transaction absente ou erreur provider : écrire uniquement l’observation technique.
|
||
|
||
## Cycle de vie
|
||
|
||
Les états de rétention de la transaction canonique restent :
|
||
|
||
```text
|
||
full
|
||
compacted
|
||
archived
|
||
purged
|
||
```
|
||
|
||
Les états de traitement restent :
|
||
|
||
```text
|
||
received
|
||
core_extracted
|
||
decoded
|
||
materialized
|
||
failed
|
||
```
|
||
|
||
Les observations sont append-only et suivent une rétention technique distincte.
|
||
|
||
## Baseline SQL active
|
||
|
||
Après validation de la transition historique, le dossier `kb_store_pg/migrations/` a été consolidé :
|
||
|
||
```text
|
||
0001_canonical_transaction_store.sql
|
||
0002_core_store.sql
|
||
```
|
||
|
||
La baseline ne contient que les tables et colonnes actives. Les anciens noms RPC/WS ne sont plus recréés. Le DDL runtime conserve temporairement un chemin de compatibilité idempotent pour les workspaces encore issus de `pre.001`.
|