4.1 KiB
4.1 KiB
Delta 0.2.9-pre.010 — reconnect borné + replay prudent + continuité observable
Base
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
YellowstoneGrpcSubscribeSnapshotavec compteurs sûrs de reconnect/replay/continuité ; - active le
YellowstoneGrpcReconnectSettingsdéjà introduit enpre.002pour le streamSubscribe; - rouvre le stream avec un backoff exponentiel borné et un nombre d'essais borné ;
- conserve le dernier
YellowstoneSubscribeRequestcomplet accepté ; - après perte du stream, resoumet ce request déterministement avec un
from_slotau moins égal au plus haut slot déjà observé ; - consulte
SubscribeReplayInfoavant les tentatives de replay lorsquefrom_slotest disponible ; - si
first_available > from_slot, incrémentecontinuity_gap_countet 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
Reconnectingpour é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é
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 :
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
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
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é.