v0.3.1-pre.004
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/022-V0_3_1_STORE_RAW_PLAN.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Plan `0.3.1` — Store API RAW foundation
|
||||
|
||||
@@ -434,61 +434,123 @@ logsSubscribe
|
||||
|
||||
Le Store n'envoie lui-même aucun événement.
|
||||
|
||||
### 6.4 `RawAccountState` et observation
|
||||
### 6.4 `RawAccountState` et observation — matrice `pre.004`
|
||||
|
||||
Les réponses account complètes provenant de HTTP, WS ou Yellowstone peuvent potentiellement converger vers un même état canonique :
|
||||
L'audit de la surface KSP réelle confirme qu'un **état complet de compte** possède une sémantique commune entre HTTP, WebSocket et Yellowstone lorsque la source fournit les bytes complets et un slot durable. Le Store ne conserve pas la forme d'encodage réseau : base58/base64/base64+zstd et protobuf doivent être décodés avant construction du modèle commun.
|
||||
|
||||
Le modèle commun matérialisé est :
|
||||
|
||||
```text
|
||||
pubkey
|
||||
slot/context utile
|
||||
lamports
|
||||
owner
|
||||
executable
|
||||
rent_epoch
|
||||
data bytes exacts
|
||||
RawAccountStateReference
|
||||
network
|
||||
pubkey
|
||||
slot
|
||||
state_hash
|
||||
|
||||
RawAccountState
|
||||
reference
|
||||
lamports
|
||||
owner
|
||||
executable
|
||||
rent_epoch
|
||||
complete data bytes
|
||||
|
||||
RawAccountObservation
|
||||
observation_key
|
||||
account reference
|
||||
provenance
|
||||
optional write_version
|
||||
optional transaction_signature
|
||||
optional is_startup
|
||||
```
|
||||
|
||||
Les détails propres à l'acquisition (`write_version`, signature source, startup, provider, transport, timing, etc.) appartiennent à `RawAccountObservation` lorsqu'ils sont utiles et disponibles.
|
||||
`state_hash` fait partie de la référence car une même account peut subir plusieurs écritures dans un slot, alors que les surfaces HTTP/WS standards n'exposent pas le `write_version` Yellowstone. Le digest permet à plusieurs sources observant **le même état complet** de converger sans promouvoir un ordinal provider-specific dans l'identité commune. Le producer/converter possède le calcul déterministe du digest ; Store API ne choisit pas l'algorithme de hash.
|
||||
|
||||
`RawAccountState`/`RawAccountObservation` doivent être **prévus dans `ksp-store-api`** après validation de la matrice de compatibilité. Leur persistence concrète PostgreSQL peut rester non implémentée au début de `0.3.2`.
|
||||
La matrice d'admission courante est :
|
||||
|
||||
Un compte demandé sous une forme déjà interprétée par le provider ne doit pas remplacer arbitrairement les bytes canoniques nécessaires à un futur decoder.
|
||||
| Source KSP | État complet commun | Slot durable | Admission `RawAccountState` |
|
||||
|------------------------------------|---------------------|---------------|-------------------------------------------------------------------------------------|
|
||||
| HTTP `getAccountInfo` | oui | oui | oui si account non-null, bytes complets et aucun `dataSlice`/`jsonParsed` |
|
||||
| HTTP `getMultipleAccounts` | oui | oui | oui par position non-null si bytes complets ; pubkey reprise depuis la requête |
|
||||
| HTTP `getProgramAccounts` | oui | conditionnel | oui seulement avec résultat contextualisé + bytes complets ; forme bare refusée |
|
||||
| WS `accountSubscribe` | oui | oui | oui si bytes complets ; pubkey reprise depuis l'identité de subscription |
|
||||
| WS `programSubscribe` | oui | conditionnel | oui seulement pour la forme contextualisée + bytes complets ; forme bare event-only |
|
||||
| Helius standard account/program WS | oui | idem standard | mêmes règles que le wire Solana standard réutilisé |
|
||||
| Yellowstone `Account` | oui | oui | oui si `accounts_data_slice` n'a pas tronqué les bytes |
|
||||
|
||||
### 6.5 Transaction status
|
||||
|
||||
Les surfaces signature/status peuvent représenter un fait distinct d'une transaction complète :
|
||||
Règles négatives :
|
||||
|
||||
```text
|
||||
signatureSubscribe
|
||||
getSignatureStatuses
|
||||
Yellowstone TransactionStatus
|
||||
provider equivalent
|
||||
jsonParsed
|
||||
request-side data slice
|
||||
Yellowstone accounts_data_slice
|
||||
program account sans context/slot
|
||||
account absent/null
|
||||
-X-> RawAccountState persistant incomplet
|
||||
```
|
||||
|
||||
Le candidat `TransactionStatusObservation` doit être étudié et, si la sémantique commune est démontrée, prévu dans l'API même si sa persistence n'est pas immédiatement implémentée.
|
||||
`space` n'est pas conservé comme vérité indépendante : lorsqu'on possède les bytes complets, leur longueur est déterministe. Les enrichissements Yellowstone `write_version`, `txn_signature` et `is_startup` appartiennent à `RawAccountObservation`. Le timestamp serveur et les filters/capture ids restent de la provenance lorsque le converter peut les représenter sans perte utile.
|
||||
|
||||
Il peut plus tard servir à un worker/analyser pour détecter des transitions de commitment/status. Ce déclenchement n'est pas une responsabilité du Store.
|
||||
|
||||
### 6.6 Slot, vote, block et Yellowstone Entry
|
||||
|
||||
Classification actuelle :
|
||||
La borne initiale Store-owned est :
|
||||
|
||||
```text
|
||||
complete account data <= 16 MiB
|
||||
```
|
||||
|
||||
Elle est un admission guard KSP, pas une affirmation sur la limite protocolaire Solana.
|
||||
|
||||
### 6.5 Transaction status — convergence insuffisante pour un modèle Store unique
|
||||
|
||||
L'audit `pre.004` conclut que les trois surfaces candidates ne représentent pas encore exactement le même fait :
|
||||
|
||||
| Source | Sémantique principale | Conclusion `0.3.1` |
|
||||
|-------------------------------|---------------------------------------------------------------------------|-----------------------------------------------------|
|
||||
| HTTP `getSignatureStatuses` | snapshot interrogé : slot, confirmations, error, confirmation status | candidat snapshot durable, non figé |
|
||||
| WS `signatureSubscribe` | event one-shot : received puis/ou commitment demandé atteint | event runtime, ownership Interface/worker à étudier |
|
||||
| Yellowstone TransactionStatus | update d'exécution : slot, signature, vote, index, error, sans commitment | event/status provider-neutral potentiel, non figé |
|
||||
|
||||
Créer maintenant un `TransactionStatusObservation` rempli d'options ferait perdre la distinction entre **snapshot interrogé**, **transition de commitment** et **update d'exécution**. Aucun modèle Store n'est donc ajouté en `pre.004`.
|
||||
|
||||
TODO avant matérialisation :
|
||||
|
||||
```text
|
||||
séparer explicitement snapshot durable vs event realtime
|
||||
étudier l'ownership ksp-interface-lib des events passifs
|
||||
prouver la correspondance des états/commitments
|
||||
prévoir un éventuel wake-up worker/analyser sans notification émise par Store
|
||||
```
|
||||
|
||||
### 6.6 Logs, slot, vote, block et Yellowstone Entry — classification fermée `pre.004`
|
||||
|
||||
Classification actuelle après audit :
|
||||
|
||||
```text
|
||||
logsSubscribe
|
||||
-> event realtime passif distinct
|
||||
-> signature + error + ordered log lines + context slot
|
||||
-> pas de RawLog Store
|
||||
-> ownership ksp-interface-lib/worker à préciser
|
||||
|
||||
slot/root/slotsUpdates
|
||||
-> event-only candidat ; persistence non justifiée actuellement
|
||||
-> event-only candidat
|
||||
-> aucune persistence N1 démontrée
|
||||
|
||||
vote
|
||||
-> event-only candidat si la forme est suffisamment commune entre les ledgers/providers qui l'exposent
|
||||
-> event-only candidat si la forme commune utile est prouvée
|
||||
-> aucune persistence N1 par défaut
|
||||
|
||||
getBlock / Yellowstone Block
|
||||
-> source/conteneur d'acquisition de RawTransaction par défaut
|
||||
RawBlock persistant seulement si un besoin block-level non reconstructible est démontré
|
||||
-> source/conteneur d'acquisition de RawTransaction
|
||||
-> RawBlock persistant reste IDEA uniquement
|
||||
|
||||
Yellowstone Entry
|
||||
-> examiné et non retenu actuellement : trop bas niveau et aucune destination replay/decomposition/event métier suffisante identifiée
|
||||
-> transport-only
|
||||
-> explicitement non retenu actuellement
|
||||
```
|
||||
|
||||
`RawBlock` reste une IDEA, pas un modèle actif. Recréer le ledger bloc par bloc sans besoin supplémentaire irait à l'encontre de l'objectif KSP de transformer la donnée blockchain en unités directement exploitables.
|
||||
Les logs contenus dans `RawTransaction` restent distincts de `logsSubscribe` : les premiers sont de la matière replayable de transaction et seront extraits en N2 STRUCTURAL ; le second est un événement realtime léger pouvant éventuellement déclencher l'hydratation de la transaction complète.
|
||||
|
||||
`RawBlock` ne doit être rouvert que si un besoin block-level non reconstructible apporte une valeur concrète au pipeline. Recréer le ledger bloc par bloc sans besoin supplémentaire irait à l'encontre de l'objectif KSP de produire des unités directement exploitables.
|
||||
|
||||
### 6.7 Modèles et capabilities sont indépendants
|
||||
|
||||
@@ -702,9 +764,25 @@ La signature ne doit pas être représentée comme un identifiant SQL `i64` dans
|
||||
|
||||
Chaque observation possède une clé d'idempotence déterministe fournie par le producer/composition selon un contrat documenté. Deux acquisitions légitimes distinctes peuvent donc être conservées même si elles pointent vers le même RAW.
|
||||
|
||||
### 10.4 Événements et autres familles
|
||||
### 10.4 Account states
|
||||
|
||||
Les événements realtime non persistés n'ont pas d'identité Store à inventer. Lorsqu'une nouvelle famille persistante est admise (`RawAccountState`, status durable, etc.), son identité d'idempotence doit être définie avec le modèle concret et ne jamais dépendre d'une primary key backend.
|
||||
La référence matérialisée par `pre.004` est :
|
||||
|
||||
```text
|
||||
RawAccountStateReference
|
||||
network
|
||||
pubkey
|
||||
slot
|
||||
canonical state hash
|
||||
```
|
||||
|
||||
Le hash couvre conceptuellement l'état canonique complet et sert à distinguer/converger les écritures multiples possibles dans un même slot sans dépendre de `write_version`. Le Store API ne calcule pas ce digest et ne transforme pas les bytes de transport.
|
||||
|
||||
Une `RawAccountObservation` possède sa propre `RawObservationKey`; plusieurs acquisitions HTTP/WS/gRPC peuvent donc viser la même référence d'état sans être fusionnées comme observations.
|
||||
|
||||
### 10.5 Événements et autres familles
|
||||
|
||||
Les événements realtime non persistés n'ont pas d'identité Store à inventer. Si une autre famille persistante est admise ultérieurement, son identité d'idempotence doit être définie avec le modèle concret et ne jamais dépendre d'une primary key backend.
|
||||
|
||||
Aucune promesse exactly-once distribuée n'est faite.
|
||||
|
||||
@@ -1293,7 +1371,7 @@ Introduire payload/reference/provenance/idempotence/timestamps bornés puis `Raw
|
||||
|
||||
### `pre.004` — Matrice cross-source + familles N1 prévues
|
||||
|
||||
Auditer HTTP/WS/gRPC pour `RawAccountState`/observation et `TransactionStatusObservation`; introduire les modèles communs seulement lorsque la sémantique converge. Classer explicitement logsSubscribe/slot/vote/block/Entry en event, IDEA ou rejet.
|
||||
Audit HTTP/WS/gRPC matérialisé. `RawAccountState`/observation sont admis avec bytes complets + slot et enrichissements source-specific séparés. `TransactionStatusObservation` est différé car snapshot HTTP, transition WS et update Yellowstone ne convergent pas encore assez. `logsSubscribe`/slot/vote restent event-only candidats, block reste conteneur/IDEA et Entry reste rejeté.
|
||||
|
||||
### `pre.005` — Capabilities backend extensibles
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/018-V0_3_1_STORE_RAW.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Validation `0.3.1` — Store API RAW foundation
|
||||
|
||||
@@ -16,7 +16,7 @@ contrats/capabilities backend externes
|
||||
cycle de rétention logique + tombstone
|
||||
```
|
||||
|
||||
`RawAccountState`/observation et `TransactionStatusObservation` doivent être audités cross-source et prévus dans l'API lorsque leur sémantique commune est prouvée. Les notifications de logs/slot/vote sont classées séparément comme candidats event-only, avec ownership Interface préféré lorsqu'elles ne sont pas persistées.
|
||||
`pre.004` prouve la convergence de `RawAccountState`/observation entre HTTP/WS/gRPC sous admission stricte bytes complets + slot. `TransactionStatusObservation` reste différé : snapshot HTTP, transition WS et update Yellowstone ne sont pas encore un fait unique. Les notifications logs/slot/vote restent event-only candidates, avec ownership Interface préféré lorsqu'elles ne sont pas persistées.
|
||||
|
||||
## 2. Gate `pre.001`
|
||||
|
||||
@@ -118,8 +118,8 @@ Toute divergence exige un usage public réel et une révision du plan.
|
||||
|--------------------------------|--------------------------|-------------------|----------------|--------------------------------------------------------------------|
|
||||
| transaction complète | N1 RAW | oui | STRUCTURAL oui | implémenter modèle + observation |
|
||||
| logs contenus dans transaction | partie de RawTransaction | via transaction | STRUCTURAL oui | préserver lossless, ne pas dupliquer en `RawLog` |
|
||||
| account state complet | N1 RAW candidat | futur oui | à déterminer | audit HTTP/WS/gRPC puis prévoir modèle/observation |
|
||||
| transaction status | observation candidat | optionnelle | non | audit signature/status sources |
|
||||
| account state complet | N1 RAW | oui à terme | pas démontré | modèle + observation matérialisés en `pre.004` |
|
||||
| transaction status | familles distinctes | non figée | non | différer : snapshot HTTP != transition WS != update Yellowstone |
|
||||
| `logsSubscribe` notification | event-only candidat | non par défaut | non | ownership Interface/worker à figer |
|
||||
| slot/root/slotsUpdates | event-only candidat | non | non | TODO use-case + compatibilité |
|
||||
| vote | event-only candidat | non | non | TODO seulement si forme commune utile |
|
||||
@@ -169,26 +169,30 @@ crate/test backend externe
|
||||
|
||||
## 8. Threat/API gates futurs
|
||||
|
||||
| Gate | Attendu | Statut initial |
|
||||
|----------------------------------|-------------------------------------------------|----------------|
|
||||
| oversized RAW payload | rejet avant allocation pathologique | `pre.003` |
|
||||
| payload Debug | aucun bytes brut | `pre.003` |
|
||||
| partial source -> RawTransaction | interdit ; contrat complet exigé | `pre.003/004` |
|
||||
| HTTP/WS/gRPC semantic mismatch | détecté par admission matrix | `pre.004` |
|
||||
| duplicate same content | `AlreadyPresent` | `pre.006` |
|
||||
| duplicate divergent content | Conflict stable | `pre.006` |
|
||||
| partial transaction+observation | interdit par atomic acquisition | `pre.005` |
|
||||
| event-only -> Store capability | absent par défaut | `pre.004/007` |
|
||||
| Interface/Store duplicate model | absent | `pre.007` |
|
||||
| page limit 0/>500 | rejet | `pre.006` |
|
||||
| SQL/backend cursor leak | absent | `pre.006/007` |
|
||||
| external backend | implémente API sans Store lib | `pre.005` |
|
||||
| processing `bool` comme vérité | absent ; future preuve version-aware documentée | `pre.006/007` |
|
||||
| purge sans policy/evidence | impossible par contrat | `pre.006/007` |
|
||||
| tombstone supprimé avec payload | interdit | `pre.006` |
|
||||
| rebackfill normal après purge | skip | `pre.006` |
|
||||
| force rehydrate implicite | interdit | `pre.006` |
|
||||
| N2/N3/N4 creep | aucune surface | `pre.007` |
|
||||
| Gate | Attendu | Statut initial |
|
||||
|---------------------------------------------|-------------------------------------------------|----------------|
|
||||
| oversized RAW payload | rejet avant allocation pathologique | `pre.003` |
|
||||
| payload Debug | aucun bytes brut | `pre.003` |
|
||||
| partial source -> RawTransaction | interdit ; contrat complet exigé | `pre.003/004` |
|
||||
| HTTP/WS/gRPC semantic mismatch | détecté par admission matrix | `pre.004` PASS |
|
||||
| account bytes partiels/parsés | refusés avant `RawAccountState` | `pre.004` PASS |
|
||||
| account sans slot durable | refusé comme état persistant | `pre.004` PASS |
|
||||
| account data Debug | aucun bytes brut | `pre.004` PASS |
|
||||
| status surfaces artificiellement fusionnées | aucun modèle commun prématuré | `pre.004` PASS |
|
||||
| duplicate same content | `AlreadyPresent` | `pre.006` |
|
||||
| duplicate divergent content | Conflict stable | `pre.006` |
|
||||
| partial transaction+observation | interdit par atomic acquisition | `pre.005` |
|
||||
| event-only -> Store capability | absent par défaut | `pre.004/007` |
|
||||
| Interface/Store duplicate model | absent | `pre.007` |
|
||||
| page limit 0/>500 | rejet | `pre.006` |
|
||||
| SQL/backend cursor leak | absent | `pre.006/007` |
|
||||
| external backend | implémente API sans Store lib | `pre.005` |
|
||||
| processing `bool` comme vérité | absent ; future preuve version-aware documentée | `pre.006/007` |
|
||||
| purge sans policy/evidence | impossible par contrat | `pre.006/007` |
|
||||
| tombstone supprimé avec payload | interdit | `pre.006` |
|
||||
| rebackfill normal après purge | skip | `pre.006` |
|
||||
| force rehydrate implicite | interdit | `pre.006` |
|
||||
| N2/N3/N4 creep | aucune surface | `pre.007` |
|
||||
|
||||
### 8.1 Matérialisation `pre.003`
|
||||
|
||||
@@ -227,6 +231,43 @@ aucun RawLog/N2 STRUCTURAL/backend/runtime ajouté
|
||||
|
||||
La complétude sémantique d'une source HTTP/WS/gRPC vers le format canonique n'est pas simulée dans Store API : elle reste le gate d'admission/conversion de `pre.004`. `pre.003` exige seulement qu'un `RawTransaction` reçoive un `RawPayload` déjà canonique complet selon son format KSP déclaré.
|
||||
|
||||
### 8.2 Matérialisation `pre.004`
|
||||
|
||||
La tranche ajoute :
|
||||
|
||||
```text
|
||||
MAX_RAW_ACCOUNT_DATA_BYTES
|
||||
RawAccountStateReference
|
||||
RawAccountState
|
||||
RawAccountObservation
|
||||
```
|
||||
|
||||
Invariants vérifiés par modèle/canaris :
|
||||
|
||||
```text
|
||||
référence = network + pubkey + slot + canonical state hash
|
||||
account data complet <= 16 MiB
|
||||
empty account data autorisé
|
||||
Debug RawAccountState ne rend jamais les bytes
|
||||
write_version/transaction_signature/is_startup restent observation-only optionnels
|
||||
HTTP/WS/gRPC source details n'entrent pas dans RawAccountState
|
||||
aucun TransactionStatusObservation artificiel
|
||||
aucun RawLogNotification/RawSlotEvent/RawVoteEvent/RawBlock/YellowstoneEntry public
|
||||
```
|
||||
|
||||
Matrice d'admission validée architecturalement :
|
||||
|
||||
```text
|
||||
getAccountInfo/getMultipleAccounts -> oui avec bytes complets
|
||||
getProgramAccounts -> contexte obligatoire
|
||||
accountSubscribe -> oui avec bytes complets
|
||||
programSubscribe -> contexte obligatoire
|
||||
Yellowstone Account -> aucun accounts_data_slice
|
||||
jsonParsed/dataSlice/bare program -> non
|
||||
```
|
||||
|
||||
La conversion source -> modèle reste hors `ksp-store-api`; la crate ne dépend toujours que de `ksp-core-lib`.
|
||||
|
||||
## 9. Gates de fermeture prévus
|
||||
|
||||
### Gate technique final `pre.008`
|
||||
@@ -317,7 +358,7 @@ sécurité
|
||||
| `pre.001` | audit/design/taxonomie/split | PRÊT après gate local |
|
||||
| `pre.002` | scaffold + taxonomie Store API | À FAIRE |
|
||||
| `pre.003` | primitives + RawTransaction | À FAIRE |
|
||||
| `pre.004` | admission matrix + account/status models | À FAIRE |
|
||||
| `pre.004` | admission matrix + account/status models | PRÊT après gate local |
|
||||
| `pre.005` | backend contracts/capabilities | À FAIRE |
|
||||
| `pre.006` | queries/outcomes/retention/tombstone | À FAIRE |
|
||||
| `pre.007` | boundary/adversarial/completeness | À FAIRE |
|
||||
|
||||
Reference in New Issue
Block a user