334 lines
11 KiB
Markdown
334 lines
11 KiB
Markdown
<!-- file: deltas/0.3.14/pre.003.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.3.14-pre.003` — observabilité latest-value de continuité WebSocket
|
|
|
|
## Base requise
|
|
|
|
```text
|
|
0.3.14-pre.002-fix.002
|
|
workspace.package.version = 0.3.14-pre.2.fix.2
|
|
deltas/0.3.14/pre.002-fix.002.md présent
|
|
```
|
|
|
|
## Gate de la base
|
|
|
|
Le gate opérateur de `0.3.14-pre.002-fix.002` est validé avant ouverture de cette tranche :
|
|
|
|
```text
|
|
cargo fmt --all : PASS
|
|
cargo fmt --all -- --check : PASS
|
|
audit Rust workspace rules : PASS
|
|
audit Markdown tables : PASS
|
|
cargo check --workspace : PASS
|
|
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS
|
|
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features : PASS
|
|
```
|
|
|
|
Le gate Worker comprend notamment :
|
|
|
|
```text
|
|
114 unit tests : PASS
|
|
cross_layer_completeness : 8 PASS
|
|
dependency_boundary : 19 PASS
|
|
hardening : 27 PASS
|
|
public_api : 20 PASS
|
|
release_completeness : 5 PASS
|
|
```
|
|
|
|
## Objectif
|
|
|
|
Implémenter strictement la tranche `pre.003` du plan `035` :
|
|
|
|
```text
|
|
ajouter dans Transport une source latest-value sûre pour les snapshots WebSocket typés
|
|
la déléguer depuis les façades Standard et Helius existantes
|
|
observer les incidents reconnect/overflow dans les sources Standard Logs, Standard Block et Helius du Worker
|
|
ancrer un incident sur le dernier slot réellement observé par cette source
|
|
borner l'incident avec le premier slot post-incident réellement reçu
|
|
conserver une terminalité conservative tant que les tranches de replay/repair ultérieures ne sont pas présentes
|
|
ne créer aucun nouveau socket, actor, retry ou repair HTTP
|
|
```
|
|
|
|
Cette tranche ne remplace pas encore un gap WebSocket par une réparation. Elle rend l'incident explicitement observable et bornable en réutilisant exclusivement les snapshots déjà publiés par l'actor Transport existant.
|
|
|
|
## Transport — source latest-value WebSocket
|
|
|
|
`WsSession` possède déjà un `tokio::sync::watch::Receiver<WsSessionSnapshot>` interne utilisé pour `snapshot()` et `state()`.
|
|
|
|
`pre.003` ajoute `WsSessionSnapshotSource`, un observateur cloneable qui encapsule uniquement un clone de ce receiver et expose :
|
|
|
|
```text
|
|
current() -> dernier WsSessionSnapshot sûr
|
|
wait_for_change() -> prochaine valeur latest-value, ou None si l'actor disparaît
|
|
```
|
|
|
|
Le type ne contient ni URL, ni credentials, ni socket, ni payload de notification. Son `Debug` reste fondé sur la projection sûre existante.
|
|
|
|
`WsSession::snapshot_source()` clone le receiver existant. Les façades :
|
|
|
|
```text
|
|
SolanaStandardWsSession
|
|
HeliusLaserStreamWsSession
|
|
```
|
|
|
|
délèguent cette méthode au même `WsSession` physique. Aucun second runtime WebSocket n'est créé.
|
|
|
|
## Worker — ancre d'incident WebSocket
|
|
|
|
Le Worker introduit un contrat crate-private `RawTransactionIngestWebSocketIncidentAnchor`.
|
|
|
|
Il conserve uniquement :
|
|
|
|
```text
|
|
start_slot
|
|
end_slot optionnel
|
|
compteurs de continuity gap / overflow observés au moment de l'incident
|
|
motifs reconnect et/ou overflow
|
|
```
|
|
|
|
La borne de début respecte le plan `035` :
|
|
|
|
```text
|
|
start_slot = dernier slot réellement observé par la source avant l'incident
|
|
```
|
|
|
|
Aucun timestamp, frontier dérivé d'une autre source ou `last_slot + 1` n'est utilisé comme preuve de début.
|
|
|
|
La borne de fin est :
|
|
|
|
```text
|
|
end_slot = premier slot réellement reçu par la même source après l'incident
|
|
```
|
|
|
|
Le range reste inclusif. Les validations réutilisent les bornes run-local introduites en `pre.002` et rejettent notamment inversion, dépassement de plage et compteur régressif.
|
|
|
|
Si un reconnect/overflow est observé avant qu'un slot source n'ait été vu, le Worker ne fabrique pas d'historique : l'incident est `source.websocket_incident_unbounded`.
|
|
|
|
## Worker — observation des snapshots
|
|
|
|
`RawTransactionIngestProcessingFrontierReporter` observe maintenant les `WsSessionSnapshot` Transport et maintient :
|
|
|
|
```text
|
|
continuity gap total WebSocket
|
|
notification overflow total
|
|
ancre d'incident WebSocket éventuelle
|
|
projection de lifecycle source
|
|
```
|
|
|
|
Une source redevenue `Active` reste projetée `Reconnecting` tant qu'un incident ouvert n'a pas reçu sa borne post-incident. Cela évite de publier transitoirement une continuité saine alors que le gap n'est pas encore borné.
|
|
|
|
Aucune mutation de la politique de reconnect Transport n'est effectuée par le Worker.
|
|
|
|
## Standard Logs et Helius transaction
|
|
|
|
Les deux sources réutilisent maintenant `session.snapshot_source()` en parallèle de la réception métier et des tâches d'hydration existantes.
|
|
|
|
Lorsqu'un incident est détecté :
|
|
|
|
```text
|
|
le premier signal post-incident borne le range de manière inclusive
|
|
ce signal est quand même admis dans le coordinator d'hydration existant
|
|
aucune nouvelle notification n'est admise après cette borne dans pre.003
|
|
les signaux/tâches déjà admis sont drainés
|
|
la source termine ensuite par source.continuity_gap_proven
|
|
```
|
|
|
|
Ce séquencement évite de perdre artificiellement le premier événement post-incident tout en restant fail-closed tant que les tranches de repair ne sont pas implémentées.
|
|
|
|
## Standard Block
|
|
|
|
La source Standard Block observe le même snapshot latest-value Transport.
|
|
|
|
Le premier bloc post-incident :
|
|
|
|
```text
|
|
borne l'incident
|
|
projette et envoie toutes ses ingresses via l'admission centrale existante
|
|
marque ensuite le slot settled
|
|
termine enfin par source.continuity_gap_proven
|
|
```
|
|
|
|
Un bloc sans transaction qualifiée peut quand même fermer la borne de slot et est settled avant la terminalité conservative.
|
|
|
|
## Yellowstone
|
|
|
|
Le chemin Yellowstone existant reste inchangé fonctionnellement dans cette tranche :
|
|
|
|
```text
|
|
aucune mutation Worker de from_slot
|
|
aucun ownership Worker de SubscribeReplayInfo
|
|
aucune nouvelle tentative de replay
|
|
aucune modification du contrat Transport Yellowstone
|
|
```
|
|
|
|
La preuve de replay native et la distinction `replay_attempt` / couverture effective restent réservées à `pre.004`.
|
|
|
|
## Tests ajoutés/étendus
|
|
|
|
Transport couvre :
|
|
|
|
```text
|
|
source latest-value courante
|
|
publication d'un changement
|
|
fermeture de la source lorsque l'actor publisher disparaît
|
|
accessibilité crate-root de WsSessionSnapshotSource
|
|
présence des délégations Standard/Helius
|
|
réutilisation du watch actor existant sans second runtime
|
|
```
|
|
|
|
Worker couvre :
|
|
|
|
```text
|
|
ancre inclusive et bornée
|
|
extension monotone d'un incident reconnect/overflow
|
|
rejet d'un incident sans motif
|
|
rejet de range inversé ou surdimensionné
|
|
incident sans slot précédent -> erreur explicite
|
|
compteurs WebSocket régressifs -> erreur explicite
|
|
reconnect et overflow successifs -> même ancre la plus ancienne
|
|
absence de socket/retry/from_slot possédé par le Worker
|
|
```
|
|
|
|
## Fichiers ajoutés
|
|
|
|
```text
|
|
deltas/0.3.14/pre.003.md
|
|
```
|
|
|
|
## Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-onchain-transport-lib/src/lib.rs
|
|
crates/ksp-onchain-transport-lib/src/ws_protocol_session.rs
|
|
crates/ksp-onchain-transport-lib/src/ws_session.rs
|
|
crates/ksp-onchain-transport-lib/tests/public_api.rs
|
|
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
|
crates/ksp-onchain-transport-lib/unit_tests/ws_session.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/src/lib.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/continuity.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
|
|
```
|
|
|
|
## Fichiers supprimés
|
|
|
|
```text
|
|
aucun
|
|
```
|
|
|
|
## Version Cargo
|
|
|
|
Conformément à `VER-ID-009`, cette nouvelle prerelease synchronise la version workspace :
|
|
|
|
```text
|
|
header Cargo.toml : 569 -> 570
|
|
workspace.package.version : 0.3.14-pre.2.fix.2 -> 0.3.14-pre.3
|
|
```
|
|
|
|
Versions des fichiers modifiés :
|
|
|
|
```text
|
|
ksp-onchain-transport-lib/src/lib.rs : 47 -> 48
|
|
ksp-onchain-transport-lib/src/ws_protocol_session.rs : 6 -> 7
|
|
ksp-onchain-transport-lib/src/ws_session.rs : 14 -> 15
|
|
ksp-onchain-transport-lib/tests/public_api.rs : 52 -> 53
|
|
ksp-onchain-transport-lib/tests/release_completeness.rs : 44 -> 45
|
|
ksp-onchain-transport-lib/unit_tests/ws_session.rs : 11 -> 12
|
|
ksp-worker-raw-transaction-ingest-lib/src/continuity.rs : 3 -> 4
|
|
ksp-worker-raw-transaction-ingest-lib/src/lib.rs : 28 -> 29
|
|
ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs : 29 -> 30
|
|
ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs : 26 -> 27
|
|
ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs : 21 -> 22
|
|
ksp-worker-raw-transaction-ingest-lib/unit_tests/continuity.rs : 2 -> 3
|
|
ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs : 23 -> 24
|
|
```
|
|
|
|
## Frontières préservées
|
|
|
|
```text
|
|
aucun repair HTTP
|
|
aucun nouveau socket WebSocket
|
|
aucun second actor WebSocket
|
|
aucun retry Worker
|
|
aucune nouvelle dépendance
|
|
aucune nouvelle feature
|
|
aucun changement Config
|
|
aucun changement Store
|
|
aucun changement Job Backfill
|
|
aucun backend Store physique depuis Worker
|
|
aucune mutation Worker de Yellowstone from_slot
|
|
aucun SubscribeReplayInfo possédé par Worker
|
|
aucun élargissement de la façade publique Worker
|
|
src/lib.rs Worker reste exempt de ReplayInfo/from_slot/repair/backfill
|
|
```
|
|
|
|
## Validations exécutées
|
|
|
|
Dans le sandbox de préparation :
|
|
|
|
```text
|
|
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
|
|
scan exact ReplayInfo/from_slot/repair/backfill dans Worker src/lib.rs
|
|
scan de possession WebSocket directe dans Worker
|
|
scan set_from_slot dans les sources de production Worker
|
|
comparaison exacte 0.3.14-pre.002-fix.002 -> 0.3.14-pre.003
|
|
contrôle des versions de fichier modifiées
|
|
contrôle du contenu de l'archive delta
|
|
unzip -t de l'archive delta
|
|
réapplication de l'archive sur la base puis comparaison byte-exacte
|
|
```
|
|
|
|
## Validations non exécutées
|
|
|
|
Le sandbox de préparation ne fournit pas le toolchain Cargo/Rust. Les gates suivants restent donc explicitement à exécuter côté opérateur :
|
|
|
|
```text
|
|
cargo fmt --all
|
|
cargo fmt --all -- --check
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
cargo test -p ksp-onchain-transport-lib --all-targets --all-features
|
|
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features
|
|
```
|
|
|
|
## Décisions prises
|
|
|
|
```text
|
|
l'observabilité WS réutilise le watch latest-value déjà possédé par Transport
|
|
le Worker observe mais ne pilote pas la reconnexion WebSocket
|
|
un gap WS commence au dernier slot source réellement observé, inclusivement
|
|
le premier slot source post-incident est la borne de fin inclusive
|
|
aucune histoire antérieure n'est inventée sans ancre source
|
|
le premier événement post-incident est admis avant la terminalité conservative
|
|
pre.003 reste fail-closed et ne prétend pas encore réparer le gap
|
|
```
|
|
|
|
## Questions ouvertes
|
|
|
|
```text
|
|
aucune pour pre.003
|
|
```
|
|
|
|
## Tranche suivante
|
|
|
|
`pre.004` reste dédiée à la preuve de replay natif Yellowstone : qualification de `SubscribeReplayInfo`, preuve de couverture effective et conservation stricte de l'ownership `from_slot` dans Transport.
|
|
|
|
## Gate opérateur après application
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
cargo fmt --all -- --check
|
|
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
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
cargo test -p ksp-onchain-transport-lib --all-targets --all-features
|
|
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features
|
|
```
|