8.2 KiB
Delta 0.3.3-pre.004 — mapping PostgreSQL privé et lectures RawTransaction
1. Base requise
0.3.3-pre.3.fix.3
Le gate opérateur fourni pour pre.003-fix.003 est entièrement vert :
cargo fmt --all PASS
audit Rust général / exports / workspace PASS
audit Markdown PASS — 214 tables / 136 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 — 19 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
La V001 split, son contrat catalogue et les politiques schema_autocreate/schema_autoupdate sont donc considérés acquis.
2. Objectif
Implémenter la tranche lecture de la vertical slice PostgreSQL RawTransaction sans ouvrir encore les écritures ni la pagination :
mapping SQL privé
get_raw_transaction
get_raw_transaction_observation
get_raw_transaction_retention_state
get_raw_transaction_tombstone
Les méthodes du backend retournent uniquement des modèles ksp-store-api. Aucun tokio_postgres::Row, SQL, SQLSTATE ou bind ne traverse le bridge public.
3. Version
Le workspace passe à :
0.3.3-pre.4
4. Module physique privé
Nouveau module :
crates/ksp-store-postgres-lib/src/raw_transaction.rs
Il possède les SELECT et les codecs physiques de cette tranche. runtime.rs ne contient aucun SQL métier et délègue les quatre lectures au module privé.
La tranche reste strictement read-only :
INSERT INTO absent
UPDATE absent
DELETE FROM absent
Les écritures canonique/observation restent pre.005; list_raw_transactions et le cursor restent pre.006.
5. Conversion physique exacte
Le mapping respecte les contrats ksp-store-api sans narrowing :
slot NUMERIC(20,0) -> PostgreSQL ::text -> parse u64
format_version BIGINT -> u32::try_from
block/observed/received BIGINT -> u64::try_from -> RawTimestamp
source payload size BIGINT -> u64::try_from + borne API
signature -> BYTEA exactement 64 bytes
hash/key -> BYTEA exactement 32 bytes
format/provenance codes -> constructeurs API fallibles
Le chemin slot couvre explicitement :
0
i64::MAX
i64::MAX + 1
u64::MAX
Aucune dépendance décimale supplémentaire n'est introduite.
6. get_raw_transaction
La requête lit la ligne canonique avec LEFT JOIN du payload archive.
Décodage :
Full
payload chaud obligatoire
payload archive interdit
-> Some(RawTransaction)
Archived
payload chaud absent
payload archive obligatoire
-> Some(RawTransaction)
Purged
payload chaud absent
payload archive absent
block_time absent
-> None
Toute incohérence de forme, entier hors domaine, code invalide, signature/hash mal dimensionné ou payload incompatible produit DataInvalid sans conserver la valeur hostile.
7. Observation
get_raw_transaction_observation reconstruit :
observation_key
transaction signature
provider
protocol
acquisition_method
origin
received_at
capture_session_id optionnel
commitment optionnel
endpoint_id optionnel
filter_id optionnel
observed_at optionnel
source_payload_hash optionnel
source_payload_size_bytes optionnel
RawObservationKey ne porte pas de réseau ; le RawTransactionReference reconstruit utilise donc exclusivement le réseau mono-backend déjà vérifié à l'ouverture.
L'ordre temporel observed_at <= received_at est revalidé par le constructeur API.
8. Rétention et tombstone
get_raw_transaction_retention_state mappe uniquement les états physiques supportés par V001 :
full
archived
purged
Une valeur inconnue ou compacted stockée physiquement est une corruption DataInvalid; Compacted n'a toujours aucune représentation PostgreSQL prétendue.
get_raw_transaction_tombstone retourne Some uniquement pour Purged, vérifie également que block_time est absent, puis reconstruit exactement :
network + signature
slot
format_id
format_version
content_hash
Pour Full ou Archived, le résultat est None.
9. Réseau pré-I/O
Les trois lectures portant un RawTransactionReference passent par un garde privé commun avant pool.get() :
reference.network == backend.network -> continuer
sinon -> WrongNetwork
Le mauvais réseau ne consomme donc aucune connexion PostgreSQL et ne dépend d'aucun SQL.
10. Erreurs backend
PostgresBackendErrorKind ajoute :
DataInvalid
ReadFailed
WrongNetwork
Classification :
pool wait/connect -> kinds existants PoolTimeout/ConnectFailed
SELECT/driver read -> ReadFailed
row/cardinality/model -> DataInvalid
reference mauvais réseau -> WrongNetwork
PostgresBackendError reste composé uniquement de :
kind
phase &'static str
Aucune erreur externe n'est retenue ni rendue.
11. Surface backend
PostgresBackend expose désormais :
get_raw_transaction
get_raw_transaction_observation
get_raw_transaction_retention_state
get_raw_transaction_tombstone
Ces méthodes ne constituent pas encore les implémentations finales des traits RawTransaction* : RawTransactionRead exige également list_raw_transactions, réservé à pre.006. Les six traits seront complets avant leur dispatch par ksp-store-lib en pre.008.
12. Tests déterministes
Le nouveau miroir unit_tests/raw_transaction.rs couvre notamment :
Full u64::MAX
Archived u64::MAX
Purged -> None
résidu payload/block_time sur Purged -> DataInvalid
provenance complète/optionnelle
source payload max
slot > u64::MAX -> DataInvalid
hash mal dimensionné -> DataInvalid
origin hostile -> DataInvalid sans écho
états Full/Archived/Purged
Compacted physique -> DataInvalid
tombstone u64::MAX/u32::MAX
wrong-network pré-I/O
Les canaris d'intégration figent également :
module SQL privé
aucun write SQL en pre.004
aucune dépendance nouvelle
surface publique sans types PostgreSQL
nouveaux error kinds sûrs
13. Migrations
Aucune ressource de migration n'est modifiée.
Les checksums restent :
V000 d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450
V001 31488cda2f08f3f46c4cdbdbb6c18c243662fada02eac4487040c8735d72cc51
14. Fichiers ajoutés
crates/ksp-store-postgres-lib/src/raw_transaction.rs
crates/ksp-store-postgres-lib/unit_tests/raw_transaction.rs
deltas/0.3.3/pre.004.md
15. Fichiers modifiés
Cargo.toml
crates/ksp-store-postgres-lib/README.md
crates/ksp-store-postgres-lib/USAGE.md
crates/ksp-store-postgres-lib/src/error.rs
crates/ksp-store-postgres-lib/src/lib.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
docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md
docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md
16. Fichiers supprimés
Aucun.
17. Hors scope confirmé
Aucun changement n'est apporté à :
ksp-store-api contrats
ksp-store-lib dispatch métier
écriture RawTransaction
écriture observation
pagination/cursor
transition rétention
RawAccountState
worker/job/app
migration SQL V000/V001
18. Gate opérateur
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.3
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
La tranche n'est validée qu'après gate opérateur entièrement vert.