Files
khadhroony-solana-project/crates/ksp-store-postgres-lib
..
2026-08-30 21:37:02 +02:00
2026-08-30 23:15:48 +02:00
2026-08-30 23:25:12 +02:00
2026-08-30 22:54:53 +02:00
2026-08-29 19:53:00 +02:00
2026-08-30 17:46:49 +02:00
2026-08-30 17:46:49 +02:00

ksp-store-postgres-lib

ksp-store-postgres-lib est le backend PostgreSQL physique officiel du Store KSP.

La crate implémente connexion, pool, TLS, migrations, health et persistence RAW derrière ksp-store-lib. Elle dépend directement de ksp-store-api mais ne dépend jamais de la façade ksp-store-lib.

Responsabilités

La crate possède seule pour PostgreSQL :

  • le parsing et la normalisation de la configuration physique tokio-postgres ;
  • le pool borné deadpool-postgres ;
  • la policy TLS physique avec Rustls ;
  • les roots système et le provider cryptographique AWS-LC ;
  • le bootstrap et le moteur de migrations privé KSP ;
  • la table metadata ksp_store_schema_migrations ;
  • l'advisory transaction lock borné des migrations ;
  • le schéma physique et les statements privés RawTransaction ;
  • les snapshots runtime/health sûrs destinés au bridge de façade ;
  • la fermeture explicite du pool et son fallback Drop best-effort ;
  • la classification d'erreurs backend sans conserver le texte d'erreur PostgreSQL.

Frontière d'utilisation

Les applications, jobs et workers KSP ne dépendent normalement pas de cette crate :

consumer -> ksp-store-lib -> [feature postgres] ksp-store-postgres-lib

La surface publique de cette crate existe pour le bridge inter-crates et les tests/intégrations backend. Elle ne constitue pas une seconde façade Store.

ksp-store-postgres-lib ne réexporte pas tokio-postgres, Deadpool ou Rustls.

Connexion et pool

PostgresBackend::open :

  1. valide et normalise l'URI fournie explicitement ;
  2. impose la policy TLS typée ;
  3. construit un pool borné ;
  4. prouve une connexion physique ;
  5. vérifie/applique le bootstrap selon les settings ;
  6. ne retourne qu'après succès de cette fondation.

Le backend ne lit aucun environnement, .env, PG*, .pgpass ou fichier TLS implicite libpq.

TLS

Les modes sont exactement :

Disabled
VerifyFull

VerifyFull exige TLS, roots système, certificat valide et vérification de l'identité serveur. Une configuration ne permettant pas de vérifier cette identité, comme hostaddr seul, est rejetée.

Migrations et schéma

Le moteur de migrations embarqué vérifie version logique, nom et checksum SHA-256, sérialise les runners par advisory transaction lock et refuse une history divergente ou plus récente que le runtime.

Le bootstrap metadata est conservé comme migration V000. La migration logique V001 matérialise le schéma RawTransaction en ressources séparées tables/, constraints/ et indexes/ afin que le backend puisse vérifier leur compatibilité effective sans transformer les fichiers SQL en parser généraliste.

La base est liée à un seul RawNetworkId via ksp_store_identity. Une migration enregistrée mais physiquement divergente est un mismatch ; les réparations additives sûres dépendent de schema_autoupdate.

Health et erreurs

PostgresBackendRuntimeSnapshot et PostgresBackendHealthSnapshot ne contiennent que des compteurs et états sûrs destinés à la façade.

PostgresBackendError ne conserve que :

PostgresBackendErrorKind
phase statique

Le texte d'erreur PostgreSQL, l'URI, SQL et les valeurs bind ne traversent pas cette frontière.

Support PostgreSQL

Le major minimal supporté est PostgreSQL 15. Le backend ne fixe aucun plafond arbitraire de major ; la compatibilité opérationnelle reste fondée sur le contrat de schéma KSP et l'introspection du catalogue.

Lectures RAW transaction

Le backend expose :

get_raw_transaction
get_raw_transaction_observation
get_raw_transaction_retention_state
get_raw_transaction_tombstone

Le SQL et les rows restent privés. Le mapping PostgreSQL est fallible et couvre notamment NUMERIC(20,0) -> u64, BIGINT -> u32/u64, timestamps bornés, bytes de taille fixe et codes de provenance.

Full lit le payload chaud, Archived le reconstruit depuis la relation archive et Purged retourne None; le tombstone reste accessible séparément.

Écritures RAW transaction

Le backend expose :

persist_raw_transaction_acquisition
record_raw_transaction_observation

L'acquisition canonique et son observation initiale sont commises dans une seule transaction PostgreSQL. Les clés uniques physiques fournissent l'admission idempotente ; après un conflit unique, le backend verrouille la ligne gagnante et compare le contenu réel avant de conclure AlreadyPresent ou Conflict.

Un tombstone Purged compatible produit SkippedPurged/NotRecorded en mode normal. ForceRehydrate restaure explicitement le payload Full et l'observation dans la même transaction.

Pagination RAW transaction

list_raw_transactions parcourt les références canoniques récupérables avec un ordre total (slot, signature). Les tombstones Purged sont exclus.

La continuation est une keyset stricte, jamais un OFFSET. Le cursor backend V1 est opaque et lié au réseau, à la direction et aux bornes de slots de la query. Store n'impose aucun plafond métier arbitraire à la taille de page ; seule la limitation physique du LIMIT + 1 PostgreSQL est exposée.

Rétention RAW transaction

transition_raw_transaction_retention applique les transitions physiques :

Full -> Archived -> Purged

Le backend verrouille la ligne canonique avec FOR UPDATE, compare l'état courant à l'état attendu et applique la mutation atomiquement. L'archivage conserve le payload exact dans la relation archive ; la purge conserve seulement le tombstone minimal.

Toute transition impliquant Compacted est rejetée avec RetentionCompactionUnsupported tant qu'aucune représentation compactée réelle n'est implémentée.

Hors périmètre

La crate ne contient :

  • aucune implémentation PostgreSQL des capabilities RawAccount* ;
  • aucune orchestration worker/job ;
  • aucun transport d'acquisition ou decoder Program ;
  • aucune policy autonome de batch, priorité ou rétention.

Documentation