Files
2026-08-30 22:47:33 +02:00

6.3 KiB

Delta 0.3.4-pre.007 — pagination account keyset + cursor KSPA

1. Base requise

0.3.4-pre.6

Le gate opérateur fourni le 2026-08-30 pour pre.006 est entièrement vert :

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 :

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 à :

0.3.4-pre.7

4. Requêtes physiques

raw_account.rs ajoute quatre SELECT privés :

sans pubkey : ASC / DESC
avec pubkey : ASC / DESC

L'ordre total est :

ASC  (slot ASC,  pubkey ASC,  state_hash ASC)
DESC (slot DESC, pubkey DESC, state_hash DESC)

Les continuations utilisent exclusivement :

(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é :

crates/ksp-store-postgres-lib/src/raw_account/cursor.rs

Format fixe :

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 :

KSP/raw-account-state-cursor/v1

Le digest lie :

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 :

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 :

pubkey     exact 32 bytes
slot       NUMERIC(20,0)::text -> u64 exact
state_hash exact 32 bytes

Le résultat public du bridge est exclusivement :

RawPage<RawAccountStateReference>

Aucun row PostgreSQL, SQL ou cursor décodé ne traverse la frontière backend.

8. Bridge backend

PostgresBackend expose :

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 :

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 :

ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e

10. Fichiers ajoutés

crates/ksp-store-postgres-lib/src/raw_account/cursor.rs
deltas/0.3.4/pre.007.md

11. Fichiers modifiés

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

aucun

13. Validations exécutées à l'assemblage

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

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.