249 lines
6.3 KiB
Markdown
249 lines
6.3 KiB
Markdown
<!-- file: deltas/0.3.4/pre.007.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.3.4-pre.007` — pagination account keyset + cursor `KSPA`
|
|
|
|
## 1. Base requise
|
|
|
|
```text
|
|
0.3.4-pre.6
|
|
```
|
|
|
|
Le gate opérateur fourni le 2026-08-30 pour `pre.006` est entièrement vert :
|
|
|
|
```text
|
|
cargo fmt --all PASS
|
|
audit Rust général / exports / workspace PASS
|
|
audit Markdown PASS — 239 tables / 143 files
|
|
cargo check --workspace PASS
|
|
cargo clippy --workspace --all-targets PASS
|
|
cargo test -p ksp-store-api PASS
|
|
cargo test -p ksp-store-lib PASS
|
|
cargo test -p ksp-store-postgres-lib PASS — 58 unit tests + canaris, live ignored
|
|
cargo test -p ksp-config-lib PASS — 128 unit tests + ownership/public API
|
|
cargo check -p ksp-store-lib --no-default-features PASS
|
|
```
|
|
|
|
L'observation supplémentaire account et son contrat transactionnel/cancellation sont donc considérés acquis.
|
|
|
|
## 2. Objectif
|
|
|
|
Implémenter uniquement la navigation `RawAccountStateQuery` :
|
|
|
|
```text
|
|
ordre total (slot, pubkey, state_hash)
|
|
ASC / DESC complètement inversés
|
|
filtre pubkey optionnel
|
|
bornes de slot inclusives
|
|
keyset pagination uniquement
|
|
cursor account KSPA V1
|
|
LIMIT + 1 sans policy KSP
|
|
```
|
|
|
|
Les quatre capabilities account et leur dispatch `Store` restent hors tranche jusqu'à `pre.008`.
|
|
|
|
## 3. Version
|
|
|
|
Le workspace passe à :
|
|
|
|
```text
|
|
0.3.4-pre.7
|
|
```
|
|
|
|
## 4. Requêtes physiques
|
|
|
|
`raw_account.rs` ajoute quatre SELECT privés :
|
|
|
|
```text
|
|
sans pubkey : ASC / DESC
|
|
avec pubkey : ASC / DESC
|
|
```
|
|
|
|
L'ordre total est :
|
|
|
|
```text
|
|
ASC (slot ASC, pubkey ASC, state_hash ASC)
|
|
DESC (slot DESC, pubkey DESC, state_hash DESC)
|
|
```
|
|
|
|
Les continuations utilisent exclusivement :
|
|
|
|
```text
|
|
(slot, pubkey, state_hash) > (last_slot, last_pubkey, last_state_hash)
|
|
(slot, pubkey, state_hash) < (last_slot, last_pubkey, last_state_hash)
|
|
```
|
|
|
|
Sans filtre, l'index V002 `(slot, pubkey, state_hash)` porte la navigation. Avec filtre pubkey, la PK `(pubkey, slot, state_hash)` porte le préfixe account et le même ordre déterministe.
|
|
|
|
## 5. Cursor account V1
|
|
|
|
Nouveau module privé :
|
|
|
|
```text
|
|
crates/ksp-store-postgres-lib/src/raw_account/cursor.rs
|
|
```
|
|
|
|
Format fixe :
|
|
|
|
```text
|
|
0..4 magic KSPA
|
|
4 version 1
|
|
5..13 last_slot u64 big-endian
|
|
13..45 last_pubkey 32 bytes
|
|
45..77 last_state_hash 32 bytes
|
|
77..109 SHA-256 binding digest
|
|
```
|
|
|
|
Domaine :
|
|
|
|
```text
|
|
KSP/raw-account-state-cursor/v1
|
|
```
|
|
|
|
Le digest lie :
|
|
|
|
```text
|
|
network
|
|
pubkey filter presence/value
|
|
direction
|
|
slot.start_inclusive
|
|
slot.end_inclusive
|
|
last_slot
|
|
last_pubkey
|
|
last_state_hash
|
|
```
|
|
|
|
Un cursor transaction `KSPT` ne peut donc pas être rejoué comme cursor account et échoue dès le magic.
|
|
|
|
## 6. Limite physique de page
|
|
|
|
Comme la verticale transaction, le backend applique `LIMIT + 1` uniquement pour détecter une page suivante. Aucun maximum fonctionnel KSP n'est ajouté.
|
|
|
|
La limite physique exacte reste :
|
|
|
|
```text
|
|
9_223_372_036_854_775_806
|
|
```
|
|
|
|
car `requested + 1` doit être représentable par un `i64` PostgreSQL.
|
|
|
|
## 7. Mapping de liste
|
|
|
|
Chaque row de liste revalide :
|
|
|
|
```text
|
|
pubkey exact 32 bytes
|
|
slot NUMERIC(20,0)::text -> u64 exact
|
|
state_hash exact 32 bytes
|
|
```
|
|
|
|
Le résultat public du bridge est exclusivement :
|
|
|
|
```text
|
|
RawPage<RawAccountStateReference>
|
|
```
|
|
|
|
Aucun row PostgreSQL, SQL ou cursor décodé ne traverse la frontière backend.
|
|
|
|
## 8. Bridge backend
|
|
|
|
`PostgresBackend` expose :
|
|
|
|
```text
|
|
list_raw_account_states(
|
|
&RawAccountStateQuery,
|
|
) -> RawPage<RawAccountStateReference>
|
|
```
|
|
|
|
Ce bridge reste une méthode étroite. `RawAccountStateRead`, `RawAccountStateWrite`, `RawAccountObservationRead` et `RawAccountObservationWrite` ne sont toujours pas implémentés sur `PostgresBackend`.
|
|
|
|
## 9. Scope négatif
|
|
|
|
Restent absents :
|
|
|
|
```text
|
|
OFFSET
|
|
batch max 500/1000
|
|
priority / worker policy
|
|
clamp/min artificiel
|
|
UPDATE / DELETE account
|
|
ON CONFLICT DO UPDATE
|
|
impl RawAccountStateRead for PostgresBackend
|
|
impl RawAccountStateWrite for PostgresBackend
|
|
impl RawAccountObservationRead for PostgresBackend
|
|
impl RawAccountObservationWrite for PostgresBackend
|
|
Store dispatch account
|
|
```
|
|
|
|
Toutes les migrations V000/V001/V002 restent byte-inchangées. Le checksum V002 final reste :
|
|
|
|
```text
|
|
ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e
|
|
```
|
|
|
|
## 10. Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-store-postgres-lib/src/raw_account/cursor.rs
|
|
deltas/0.3.4/pre.007.md
|
|
```
|
|
|
|
## 11. Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-store-postgres-lib/src/lib.rs
|
|
crates/ksp-store-postgres-lib/src/raw_account.rs
|
|
crates/ksp-store-postgres-lib/src/runtime.rs
|
|
crates/ksp-store-postgres-lib/tests/dependency_boundary.rs
|
|
crates/ksp-store-postgres-lib/tests/hardening_completeness.rs
|
|
crates/ksp-store-postgres-lib/tests/public_api.rs
|
|
crates/ksp-store-postgres-lib/unit_tests/raw_account.rs
|
|
docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md
|
|
docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md
|
|
```
|
|
|
|
## 12. Fichiers supprimés
|
|
|
|
```text
|
|
aucun
|
|
```
|
|
|
|
## 13. Validations exécutées à l'assemblage
|
|
|
|
```text
|
|
python3 scripts/audit_rust_workspace_rules.py PASS
|
|
python3 scripts/audit_markdown_tables.py ... deltas/0.3.4 PASS
|
|
migrations V000/V001/V002 byte-identiques à pre.006 PASS
|
|
scope pre.008 absent PASS
|
|
```
|
|
|
|
Le gate Cargo/Clippy/tests de `pre.007` doit être rejoué par l'opérateur.
|
|
|
|
## 14. Validations non exécutées
|
|
|
|
```text
|
|
cargo fmt --all
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-store-api
|
|
cargo test -p ksp-store-lib
|
|
cargo test -p ksp-store-postgres-lib
|
|
cargo test -p ksp-config-lib
|
|
cargo check -p ksp-store-lib --no-default-features
|
|
```
|
|
|
|
`cargo` n'est pas disponible dans l'environnement d'assemblage.
|
|
|
|
## 15. Décisions prises
|
|
|
|
- le cursor account reste distinct de `KSPT` par magic et domaine SHA-256 ;
|
|
- le filtre pubkey fait partie du binding du cursor ;
|
|
- les deux chemins SQL avec/sans pubkey sont séparés pour conserver une surface physique compatible avec les indexes possédés ;
|
|
- aucune policy d'exécution n'est ajoutée à la pagination Store ;
|
|
- les quatre capabilities account restent groupées pour `pre.008`.
|
|
|
|
## 16. Questions ouvertes
|
|
|
|
Aucune question bloquante pour `pre.008`.
|