95 lines
4.1 KiB
Markdown
95 lines
4.1 KiB
Markdown
<!-- file: deltas/0.2.9/pre.010.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.9-pre.010` — reconnect borné + replay prudent + continuité observable
|
|
|
|
## Base
|
|
|
|
```text
|
|
0.2.9-pre.009-fix.001
|
|
gate opérateur final : fmt/audit/check/Clippy/workspace PASS sans warning
|
|
Transport : 379 unit + 48 public API + 42 release-completeness + 4 doctests
|
|
```
|
|
|
|
## Changements runtime
|
|
|
|
- ajoute l'état public `YellowstoneGrpcSubscribeState::Reconnecting` ;
|
|
- ajoute `YellowstoneGrpcSubscribeSnapshot` avec compteurs sûrs de reconnect/replay/continuité ;
|
|
- active le `YellowstoneGrpcReconnectSettings` déjà introduit en `pre.002` pour le stream `Subscribe` ;
|
|
- rouvre le stream avec un backoff exponentiel borné et un nombre d'essais borné ;
|
|
- conserve le dernier `YellowstoneSubscribeRequest` complet accepté ;
|
|
- après perte du stream, resoumet ce request déterministement avec un `from_slot` au moins égal au plus haut slot déjà observé ;
|
|
- consulte `SubscribeReplayInfo` avant les tentatives de replay lorsque `from_slot` est disponible ;
|
|
- si `first_available > from_slot`, incrémente `continuity_gap_count` et clamp le replay à `first_available` ;
|
|
- maintient un cache borné de 512 identités d'updates pour observer les duplicates autour d'un replay ;
|
|
- les duplicates restent livrés : aucun contrat exactly-once n'est inventé ;
|
|
- rejette les mutations request pendant `Reconnecting` pour éviter une application ambiguë entre deux streams physiques ;
|
|
- un shutdown pendant le backoff interrompt immédiatement la boucle et interdit une nouvelle ouverture ;
|
|
- un épuisement du budget devient terminal avec un code KSP sûr `grpc_channel_failed`.
|
|
|
|
## Sémantique de continuité
|
|
|
|
```text
|
|
from_slot de reconnect = max(from_slot explicite du dernier request, last_observed_slot)
|
|
ReplayInfo = information de rétention ; pas preuve de replay complet
|
|
continuity gap = couverture de replay indisponible, comptée seulement si first_available > slot demandé
|
|
slot manquant entre deux updates filtrés = jamais assimilé automatiquement à un gap
|
|
duplicate = identité KSP bornée déjà observée ; update toujours livrée
|
|
exactly-once = non garanti
|
|
lossless = non garanti
|
|
ordre global sans gap = non garanti
|
|
```
|
|
|
|
Identités retenues pour l'observation bornée :
|
|
|
|
```text
|
|
Account slot + pubkey + write_version
|
|
Slot slot + status
|
|
Transaction slot + signature
|
|
TransactionStatus slot + signature
|
|
Block slot + blockhash
|
|
BlockMeta slot + blockhash
|
|
Entry slot + index + hash
|
|
Ping/Pong hors déduplication
|
|
```
|
|
|
|
La couverture d'une éventuelle divergence de node reste volontairement limitée : deux Block/BlockMeta de même slot mais de blockhash différent ne sont pas classés duplicate. KSP ne généralise pas cette preuve aux familles qui ne transportent pas de blockhash.
|
|
|
|
## Fixture locale
|
|
|
|
| Cas | Preuve |
|
|
|------------------------------------------------|-------------|
|
|
| reconnect après server half-close | PASS source |
|
|
| `from_slot = last_observed_slot` | PASS source |
|
|
| ReplayInfo disponible | PASS source |
|
|
| replay duplicate observable | PASS source |
|
|
| couverture replay indisponible prouvée + clamp | PASS source |
|
|
| budget reconnect épuisé | PASS source |
|
|
| mutation pendant reconnect rejetée | PASS source |
|
|
| shutdown pendant backoff | PASS source |
|
|
| endpoint/Status secret non réémis | PASS source |
|
|
| anciens gates bidi avec reconnect `0` | PASS source |
|
|
|
|
## Frontières
|
|
|
|
```text
|
|
OUT pre.010 : Config V3 / PublicNode / provider facade
|
|
OUT 0.2.9 : SubscribeDeshred
|
|
aucune nouvelle dépendance / feature Cargo
|
|
aucun yellowstone-grpc-client runtime
|
|
```
|
|
|
|
## Validation candidate
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
python3 scripts/audit_rust_workspace_rules.py
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-onchain-transport-lib
|
|
cargo test -p ksp-core-lib --test workspace_dependencies
|
|
cargo test --workspace
|
|
```
|
|
|
|
Le `cargo tree` n'est pas requis : aucune dépendance ni feature n'a changé.
|