v0.2.9-pre.010
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
|
||||
<!-- version: 19 -->
|
||||
<!-- version: 20 -->
|
||||
|
||||
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
|
||||
|
||||
> **Statut : `0.2.9-pre.009` est fonctionnellement verte sur gate opérateur (Transport 379 unit + 48 public API + 42 completeness + 4 doctests, workspace PASS), mais Clippy signale deux warnings d’hygiène. `0.2.9-pre.009-fix.001` est candidate pour les supprimer sans modifier le protocole ni le lifecycle ; reconnect/replay restent `pre.010`.**
|
||||
> **Statut : `0.2.9-pre.009-fix.001` est fermé sur gate opérateur intégralement vert : fmt/audit/check/Clippy sans warning, Transport 379 unit + 48 public API + 42 completeness + 4 doctests, dependency canary et workspace PASS. `0.2.9-pre.010` est candidate pour le reconnect/replay KSP-owned, les gaps de couverture replay prouvés par ReplayInfo et les duplicates observables sans promesse lossless.**
|
||||
|
||||
## 1. Objet, base et état d'ouverture
|
||||
|
||||
@@ -934,11 +934,11 @@ pre.007 DONE — standard Solana : Transactions + transaction_status
|
||||
pre.008 DONE — standard Solana : Blocks + block_meta + entry
|
||||
budget : 15–20 min ; gate final fix.001 : fmt/audit/check/Clippy/workspace PASS sans warning + Transport 370/47/41/4
|
||||
|
||||
pre.009 FIX.001 CANDIDATE — moteur partagé : bidi mutation + Ping/Pong + half-close + backpressure + shutdown
|
||||
budget : 15–20 min ; gate fonctionnel 379/48/42/4 + workspace PASS ; fix de deux warnings Clippy
|
||||
pre.009 DONE — moteur partagé : bidi mutation + Ping/Pong + half-close + backpressure + shutdown
|
||||
budget : 15–20 min ; gate final fix.001 : fmt/audit/check/Clippy/workspace PASS sans warning + Transport 379/48/42/4
|
||||
|
||||
pre.010 moteur partagé : reconnect/resubscribe + from_slot/ReplayInfo + gaps/duplicates
|
||||
budget : 15–20 min ; preuve : reconnect local déterministe + aucune promesse lossless
|
||||
pre.010 CANDIDATE — moteur partagé : reconnect/resubscribe + from_slot/ReplayInfo + gaps/duplicates
|
||||
budget : 15–20 min ; preuve source : reconnect local déterministe + ReplayInfo clamp + duplicate observable + aucune promesse lossless
|
||||
|
||||
pre.011 Config V3 + séparation protocol/provider + profils PublicNode Mainnet/Testnet
|
||||
budget : 15–20 min ; preuve : V1/V2 backward + schema/mapping/redaction + Config -> Transport
|
||||
@@ -1387,4 +1387,34 @@ Le fix applique deux corrections sans `allow` :
|
||||
|
||||
Aucun changement n’est apporté aux neuf variantes wire, à la mutation request, à Ping/Pong, au half-close, au shutdown, à la backpressure, aux dépendances ou aux frontières de `pre.010`.
|
||||
|
||||
**Gate fix requis :** fmt/audit/check/Clippy sans warning + Transport 379/48/42/4 + dependency canary + workspace.
|
||||
**Gate fix final :** fmt/audit/check/Clippy sans warning + Transport 379/48/42/4 + dependency canary + workspace **PASS le 2026-08-24**.
|
||||
|
||||
|
||||
## 28. `pre.010` — reconnect KSP-owned, reprise `from_slot` et continuité prudente
|
||||
|
||||
Le proto courant conserve `SubscribeRequest.from_slot` et le unary `SubscribeReplayInfo.first_available`. Le changelog upstream relu le `2026-08-24` confirme qu’un replay `from_slot` peut avoir des défauts spécifiques de famille : le correctif du `2026-07-22` concernait précisément des subscriptions Blocks acceptées mais reprenant live avec un state gap. KSP ne transforme donc pas la présence de `from_slot` en garantie lossless.
|
||||
|
||||
Politique retenue :
|
||||
|
||||
```text
|
||||
stream perdu -> état Reconnecting
|
||||
budget -> max_retries borné déjà dans YellowstoneGrpcReconnectSettings
|
||||
backoff -> exponentiel, initial/max bornés
|
||||
request de resubscribe -> dernier request complet accepté
|
||||
resume slot -> max(from_slot explicite, highest observed slot)
|
||||
ReplayInfo first_available > resume -> couverture replay indisponible prouvée + compteur + clamp à first_available
|
||||
ReplayInfo indisponible -> reconnect poursuit sans inférer de gap
|
||||
mutation pendant reconnect -> rejet explicite, pas de coalescing ambigu
|
||||
duplicate replay -> identité bornée comptée mais update toujours livrée
|
||||
shutdown pendant backoff -> interruption, aucune nouvelle ouverture
|
||||
```
|
||||
|
||||
`YellowstoneGrpcSubscribeSnapshot` expose `reconnect_count`, `continuity_gap_count`, `duplicate_update_count`, `replay_attempt_count`, `last_requested_from_slot`, `last_observed_slot`, l’état lifecycle et le terminal error code sûr. Le cache d’identité est borné à 512 entrées et ne contient pas les payloads arbitraires complets.
|
||||
|
||||
La détection de gap est volontairement **plus stricte** qu’un simple saut de numéro de slot : avec des filtres Accounts/Transactions/Blocks, l’absence d’update sur un slot intermédiaire peut être normale. Seule une borne de rétention `first_available` supérieure au replay demandé constitue ici une preuve objective que cette plage n'est plus rejouable ; elle ne prouve pas qu'un update correspondant aux filtres existait ou a été perdu.
|
||||
|
||||
De même, KSP ne supprime pas les duplicates : il les observe autour du replay, les compte et continue de les livrer. Cela maintient explicitement les non-promesses `exactly-once`, `lossless` et `ordre global sans gap`.
|
||||
|
||||
Couverture de divergence : les identités Block/BlockMeta incluent le blockhash ; deux histoires de même slot avec blockhash différent ne sont donc pas prises pour un duplicate. Aucune généralisation d’equivocation n’est annoncée pour les familles sans preuve de blockhash.
|
||||
|
||||
**Gate candidat :** fixture locale reconnect/replay, duplicate, gap de couverture replay, budget épuisé, mutation rejetée pendant reconnect et shutdown pendant backoff ; audit statique clean. Aucun changement de dépendance ou feature.
|
||||
|
||||
Reference in New Issue
Block a user