v0.2.9-pre.014
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 258
|
# version: 259
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
|
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.2.9-pre.13.fix.4"
|
version = "0.2.9-pre.14"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: crates/ksp-onchain-transport-lib/README.md -->
|
<!-- file: crates/ksp-onchain-transport-lib/README.md -->
|
||||||
<!-- version: 21 -->
|
<!-- version: 22 -->
|
||||||
|
|
||||||
# `ksp-onchain-transport-lib`
|
# `ksp-onchain-transport-lib`
|
||||||
|
|
||||||
@@ -242,9 +242,9 @@ Les sept unary standards retenus sont `SubscribeReplayInfo`, `Ping`, `GetLatestB
|
|||||||
|
|
||||||
Le stream bidirectionnel est borné : request/update queues, tailles inbound/outbound, half-close, close timeout et reconnect budget sont explicites. Après reconnect, KSP rejoue la dernière requête complète acceptée et avance prudemment `from_slot` selon le dernier slot observé et `SubscribeReplayInfo.first_available`. Les compteurs de gap et duplicate sont de l’observabilité ; ils ne constituent jamais une garantie exactly-once ou lossless.
|
Le stream bidirectionnel est borné : request/update queues, tailles inbound/outbound, half-close, close timeout et reconnect budget sont explicites. Après reconnect, KSP rejoue la dernière requête complète acceptée et avance prudemment `from_slot` selon le dernier slot observé et `SubscribeReplayInfo.first_available`. Les compteurs de gap et duplicate sont de l’observabilité ; ils ne constituent jamais une garantie exactly-once ou lossless.
|
||||||
|
|
||||||
Config Transport V3 peut mapper des `grpc_endpoints` vers ces settings sans inverser la dépendance. `protocol = solana_yellowstone` décrit le wire standard, tandis que `provider` reste un descripteur distinct. Le profil committé `publicnode_mainnet` utilise le standard sans credential ni façade PublicNode spécifique.
|
Config Transport V3 peut mapper des `grpc_endpoints` vers ces settings sans inverser la dépendance. `protocol = solana_yellowstone` décrit le wire standard, tandis que `provider` reste un descripteur distinct. Les profils committés `publicnode_mainnet` et `publicnode_testnet` utilisent le standard sans façade PublicNode spécifique. Leur personal token est injecté comme metadata secrète `x-token` depuis Config ; Transport ne lit jamais les variables KSP.
|
||||||
|
|
||||||
Un smoke live opt-in vérifie directement PublicNode Mainnet via `GetVersion` puis `GetSlot`. Le hostname PublicNode Testnet Yellowstone n’est pas versionné tant qu’une source officielle exploitable ne l’a pas confirmé ; KSP ne déduit pas un endpoint à partir d’une convention de nommage.
|
Le smoke live opt-in ouvre un `Subscribe` slots authentifié sur PublicNode Mainnet et Testnet, attend un update `Slot` non nul puis ferme de manière bornée. Les deux endpoints sont versionnés. Le harness reçoit ses personal tokens sur stdin ; aucun secret n’est committé ni placé dans l’URL. Le même token a été validé par l’opérateur sur les deux réseaux, même si Config conserve deux variables distinctes pour laisser cette policy flexible.
|
||||||
|
|
||||||
## Résilience
|
## Résilience
|
||||||
|
|
||||||
@@ -300,15 +300,16 @@ Transport WebSocket pur : settings programmatiques -> WsSession
|
|||||||
Composition historique : Config -> std.transport/devnet_public -> HttpTransportPool
|
Composition historique : Config -> std.transport/devnet_public -> HttpTransportPool
|
||||||
-> getHealth/getGenesisHash/getVersion/getBalance
|
-> getHealth/getGenesisHash/getVersion/getBalance
|
||||||
|
|
||||||
Transport Yellowstone gRPC : settings programmatiques -> PublicNode Mainnet
|
Transport Yellowstone gRPC : settings programmatiques + x-token secret
|
||||||
-> TLS -> GetVersion -> GetSlot confirmed
|
-> PublicNode Mainnet + Testnet
|
||||||
|
-> TLS -> Subscribe slots -> Slot non nul -> close borné
|
||||||
```
|
```
|
||||||
|
|
||||||
Le smoke HTTP Transport utilise pour sa branche Token la forme Devnet documentée `getTokenAccountsByOwner(owner, { programId }, { commitment: finalized, encoding: jsonParsed })`. L'owner est une Pubkey ordinaire de l'exemple officiel ; aucune présence de token account n'est exigée, donc une liste vide reste valide.
|
Le smoke HTTP Transport utilise pour sa branche Token la forme Devnet documentée `getTokenAccountsByOwner(owner, { programId }, { commitment: finalized, encoding: jsonParsed })`. L'owner est une Pubkey ordinaire de l'exemple officiel ; aucune présence de token account n'est exigée, donc une liste vide reste valide.
|
||||||
|
|
||||||
Le smoke WebSocket Transport cible uniquement la famille stable `slotSubscribe` sur l'endpoint public Devnet `wss://api.devnet.solana.com`. Il borne connexion, attente de notification, unsubscribe et fermeture ; il ne transforme aucune famille unstable en gate live.
|
Le smoke WebSocket Transport cible uniquement la famille stable `slotSubscribe` sur l'endpoint public Devnet `wss://api.devnet.solana.com`. Il borne connexion, attente de notification, unsubscribe et fermeture ; il ne transforme aucune famille unstable en gate live.
|
||||||
|
|
||||||
Les quatre tests sont `ignored` par défaut. Les trois smokes Transport appartiennent durablement à cette crate ; le smoke cross-crates hébergé dans Config reste transitoire jusqu'à l'existence d'une surface KSP d'intégration/orchestration appropriée. Un rate-limit, refus externe ou incident Devnet n'est pas assimilé automatiquement à une régression locale.
|
Les quatre tests sont `ignored` par défaut ; le test Yellowstone contient deux cas live Mainnet/Testnet. Les trois familles de smokes Transport appartiennent durablement à cette crate ; le smoke cross-crates hébergé dans Config reste transitoire jusqu'à l'existence d'une surface KSP d'intégration/orchestration appropriée. Un rate-limit, refus externe ou incident Devnet n'est pas assimilé automatiquement à une régression locale.
|
||||||
|
|
||||||
Aucun smoke Helius live supplémentaire n’est committé en `0.2.8-pre.010`. Un tel test devrait à la fois obtenir `KSP_SECRET_HELIUS_API_KEY` via Config et exercer Transport ; l’ajouter dans Transport violerait l’ownership environnement/secret, tandis que l’ajouter dans Config étendrait l’exception cross-crates que le projet veut au contraire résorber. La première surface KSP d’intégration/orchestration dédiée devra héberger ce smoke. Le scénario live recommandé est alors `helius_devnet -> HeliusLaserStreamWsSession -> slotSubscribe -> notification -> unsubscribe -> close`; `transactionSubscribe` reste un smoke optionnel dépendant des droits provider et ne devient pas un gate stable de release.
|
Aucun smoke Helius live supplémentaire n’est committé en `0.2.8-pre.010`. Un tel test devrait à la fois obtenir `KSP_SECRET_HELIUS_API_KEY` via Config et exercer Transport ; l’ajouter dans Transport violerait l’ownership environnement/secret, tandis que l’ajouter dans Config étendrait l’exception cross-crates que le projet veut au contraire résorber. La première surface KSP d’intégration/orchestration dédiée devra héberger ce smoke. Le scénario live recommandé est alors `helius_devnet -> HeliusLaserStreamWsSession -> slotSubscribe -> notification -> unsubscribe -> close`; `transactionSubscribe` reste un smoke optionnel dépendant des droits provider et ne devient pas un gate stable de release.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: crates/ksp-onchain-transport-lib/USAGE.md -->
|
<!-- file: crates/ksp-onchain-transport-lib/USAGE.md -->
|
||||||
<!-- version: 21 -->
|
<!-- version: 22 -->
|
||||||
|
|
||||||
# Utilisation de `ksp-onchain-transport-lib`
|
# Utilisation de `ksp-onchain-transport-lib`
|
||||||
|
|
||||||
@@ -270,14 +270,26 @@ let grpc_url = match ksp_onchain_transport_lib::YellowstoneGrpcEndpointUrl::pars
|
|||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => return Err(error),
|
Err(error) => return Err(error),
|
||||||
};
|
};
|
||||||
let grpc_endpoint = ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings::new(
|
let x_token_metadata = match ksp_onchain_transport_lib::YellowstoneGrpcMetadataEntry::secret(
|
||||||
|
"x-token",
|
||||||
|
x_token,
|
||||||
|
) {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(error) => return Err(error),
|
||||||
|
};
|
||||||
|
let grpc_endpoint = match ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings::new(
|
||||||
"publicnode_mainnet_yellowstone",
|
"publicnode_mainnet_yellowstone",
|
||||||
true,
|
true,
|
||||||
ksp_onchain_transport_lib::YellowstoneGrpcProviderName::new("publicnode"),
|
ksp_onchain_transport_lib::YellowstoneGrpcProviderName::new("publicnode"),
|
||||||
ksp_onchain_transport_lib::YellowstoneGrpcClusterName::new("mainnet-beta"),
|
ksp_onchain_transport_lib::YellowstoneGrpcClusterName::new("mainnet-beta"),
|
||||||
grpc_url,
|
grpc_url,
|
||||||
ksp_onchain_transport_lib::YellowstoneGrpcSessionSettings::default(),
|
ksp_onchain_transport_lib::YellowstoneGrpcSessionSettings::default(),
|
||||||
);
|
)
|
||||||
|
.with_metadata(vec![x_token_metadata])
|
||||||
|
{
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(error) => return Err(error),
|
||||||
|
};
|
||||||
let grpc_channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::connect(&grpc_endpoint).await {
|
let grpc_channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::connect(&grpc_endpoint).await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => return Err(error),
|
Err(error) => return Err(error),
|
||||||
@@ -289,7 +301,7 @@ let slot = grpc
|
|||||||
.await;
|
.await;
|
||||||
```
|
```
|
||||||
|
|
||||||
L’URL reste sensible : `Debug`, erreurs KSP et snapshots n’en exposent pas la valeur. Les metadata publiques/secrètes se construisent avec `YellowstoneGrpcMetadataEntry`; Transport ne lit jamais l’environnement.
|
L’URL reste sensible : `Debug`, erreurs KSP et snapshots n’en exposent pas la valeur. Les metadata publiques/secrètes se construisent avec `YellowstoneGrpcMetadataEntry`; Transport ne lit jamais l’environnement. PublicNode requiert actuellement une metadata secrète `x-token` pour les endpoints Yellowstone validés ; ici `x_token` représente une valeur déjà obtenue par un caller sécurisé. En usage normal, Config construit cette metadata depuis les variables `KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN` ou `KSP_SECRET_PUBLICNODE_TESTNET_GRPC_X_TOKEN`. Les appels unary montrés ci-dessus illustrent la surface KSP standard ; le smoke PublicNode de release ne prétend pas valider leur entitlement provider et gate uniquement `Subscribe` slots.
|
||||||
|
|
||||||
### Config Transport V3
|
### Config Transport V3
|
||||||
|
|
||||||
@@ -482,13 +494,30 @@ cargo test -p ksp-onchain-transport-lib --test websocket_devnet_smoke -- --ignor
|
|||||||
|
|
||||||
Il n'utilise ni `blockSubscribe`, ni `slotsUpdatesSubscribe`, ni `voteSubscribe` : ces familles restent unstable et leur disponibilité dépend des capabilities du validator. Le smoke live n'est donc pas un gate de disponibilité de ces extensions.
|
Il n'utilise ni `blockSubscribe`, ni `slotsUpdatesSubscribe`, ni `voteSubscribe` : ces familles restent unstable et leur disponibilité dépend des capabilities du validator. Le smoke live n'est donc pas un gate de disponibilité de ces extensions.
|
||||||
|
|
||||||
Le smoke **Transport Yellowstone gRPC PublicNode** ne dépend d’aucun secret ni de Config. Il construit l’endpoint Mainnet programmatiquement, ouvre TLS puis exerce deux unary standards peu coûteux : `GetVersion` et `GetSlot` avec commitment `confirmed` :
|
Le smoke **Transport Yellowstone gRPC PublicNode** reste indépendant de Config mais nécessite un personal token opérateur. Il teste Mainnet et Testnet en ouvrant `Subscribe`, en demandant les updates `slots`, en attendant un `YellowstoneSubscribeUpdate::Slot` non nul puis en fermant la session de manière bornée.
|
||||||
|
|
||||||
|
Pour éviter de placer les secrets dans les arguments ou l'URL, le harness lit deux lignes sur stdin : Mainnet puis Testnet. Elles peuvent contenir la même valeur ; l'opérateur a validé un même personal token sur les deux réseaux.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
|
read -rsp 'PublicNode Mainnet Yellowstone x-token: ' PUBLICNODE_MAINNET_TOKEN
|
||||||
|
echo
|
||||||
|
read -rsp 'PublicNode Testnet Yellowstone x-token: ' PUBLICNODE_TESTNET_TOKEN
|
||||||
|
echo
|
||||||
|
printf '%s\n%s\n' "$PUBLICNODE_MAINNET_TOKEN" "$PUBLICNODE_TESTNET_TOKEN" \
|
||||||
|
| cargo test -p ksp-onchain-transport-lib \
|
||||||
|
--test yellowstone_publicnode_smoke \
|
||||||
|
-- --ignored --nocapture
|
||||||
|
unset PUBLICNODE_MAINNET_TOKEN PUBLICNODE_TESTNET_TOKEN
|
||||||
```
|
```
|
||||||
|
|
||||||
Le hostname Mainnet provient directement de la page PublicNode. Le hostname Testnet n’est pas versionné dans le smoke tant qu’une source PublicNode suffisamment autoritative et exploitable ne l’a pas confirmé ; une convention de nommage ou une source tierce ne suffit pas.
|
Endpoints validés :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Mainnet https://solana-yellowstone-grpc.publicnode.com:443
|
||||||
|
Testnet https://solana-testnet-yellowstone-grpc.publicnode.com:443
|
||||||
|
```
|
||||||
|
|
||||||
|
Les profils Config conservent deux variables secrètes distinctes afin d'autoriser des credentials différents si nécessaire ; cette séparation ne signifie pas que PublicNode impose actuellement un token différent par réseau. Un timeout KSP de half-close après réception du slot est accepté par le smoke comme fermeture bornée du provider ; aucune absence de slot ni autre erreur n'est masquée.
|
||||||
|
|
||||||
Le smoke de **composition Config -> Transport** reste également disponible :
|
Le smoke de **composition Config -> Transport** reste également disponible :
|
||||||
|
|
||||||
|
|||||||
140
deltas/0.2.9/pre.014.md
Normal file
140
deltas/0.2.9/pre.014.md
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
<!-- file: deltas/0.2.9/pre.014.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta `0.2.9-pre.014` — réconciliation documentaire finale Yellowstone
|
||||||
|
|
||||||
|
## 1. Base
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.2.9-pre.013-fix.004
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette tranche est exclusivement le couloir de réconciliation documentaire défini par `VER-LIFECYCLE-006`. Elle ne modifie aucun code, test, schema, config exécutable, README global de publication, `CHANGELOG.md`, `ROADMAP.md` ou prompt suivant.
|
||||||
|
|
||||||
|
## 2. Version technique
|
||||||
|
|
||||||
|
Comme toute prerelease non-fix, la version Cargo est synchronisée mécaniquement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
workspace.package.version = 0.2.9-pre.14
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucune sémantique runtime ne change.
|
||||||
|
|
||||||
|
## 3. Preuve technique réconciliée
|
||||||
|
|
||||||
|
Le couloir `pre.013` est fermé par `pre.013-fix.004` avec :
|
||||||
|
|
||||||
|
```text
|
||||||
|
cargo fmt --all PASS
|
||||||
|
Rust workspace audit PASS, 0 export candidate
|
||||||
|
Markdown audit PASS, 87 tableaux / 258 fichiers
|
||||||
|
cargo check --workspace PASS
|
||||||
|
cargo clippy --workspace --all-targets PASS sans warning
|
||||||
|
Transport unit 383/383 PASS
|
||||||
|
Transport public API 49/49 PASS
|
||||||
|
Transport release completeness 43/43 PASS
|
||||||
|
Transport doctests 4/4 PASS
|
||||||
|
cargo test --workspace PASS
|
||||||
|
PublicNode Mainnet Subscribe + Slot PASS
|
||||||
|
PublicNode Testnet Subscribe + Slot PASS
|
||||||
|
live smoke total 2/2 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Les graphes Cargo finaux ont été inspectés dans le couloir technique. `fix.004` n'ayant modifié ni dépendance ni feature, leur verdict reste applicable :
|
||||||
|
|
||||||
|
```text
|
||||||
|
yellowstone-grpc-proto 12.6.0
|
||||||
|
tonic / tonic-prost 0.14.6
|
||||||
|
prost / prost-types 0.14.4
|
||||||
|
yellowstone-grpc-client absent du runtime KSP
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. PublicNode final
|
||||||
|
|
||||||
|
Endpoints validés :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Mainnet https://solana-yellowstone-grpc.publicnode.com:443
|
||||||
|
Testnet https://solana-testnet-yellowstone-grpc.publicnode.com:443
|
||||||
|
```
|
||||||
|
|
||||||
|
Les essais live ont montré qu'une connexion sans credential peut atteindre le service mais recevoir `PERMISSION_DENIED`. Les profils finaux utilisent donc une metadata gRPC secrète `x-token`.
|
||||||
|
|
||||||
|
Config conserve :
|
||||||
|
|
||||||
|
```text
|
||||||
|
KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN
|
||||||
|
KSP_SECRET_PUBLICNODE_TESTNET_GRPC_X_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
L'opérateur a prouvé qu'un même personal token peut être utilisé pour les deux endpoints. Les variables restent distinctes par flexibilité opérationnelle ; KSP ne transforme pas ce choix en affirmation provider de tokens network-scoped.
|
||||||
|
|
||||||
|
Le smoke Transport pur reste indépendant de Config : ses deux tokens sont fournis sur stdin au harness et ne sont jamais versionnés, placés dans l'URL ou journalisés.
|
||||||
|
|
||||||
|
## 5. Smoke final documenté
|
||||||
|
|
||||||
|
Le smoke PublicNode ne teste plus `GetVersion/GetSlot` comme preuve provider, car ces unary peuvent être restreintes indépendamment du service de streaming. La preuve représentative de `0.2.9` est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
TLS
|
||||||
|
-> metadata secret x-token
|
||||||
|
-> Subscribe
|
||||||
|
-> filtre slots
|
||||||
|
-> YellowstoneSubscribeUpdate::Slot
|
||||||
|
-> slot > 0
|
||||||
|
-> fermeture bornée
|
||||||
|
```
|
||||||
|
|
||||||
|
Mainnet et Testnet sont tous deux passés en live. Un timeout KSP de half-close n'est accepté par le harness qu'après réception prouvée du slot ; le runtime conserve son erreur explicite de timeout.
|
||||||
|
|
||||||
|
## 6. Documents réconciliés
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md
|
||||||
|
docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md
|
||||||
|
crates/ksp-onchain-transport-lib/README.md
|
||||||
|
crates/ksp-onchain-transport-lib/USAGE.md
|
||||||
|
docs/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Les anciennes affirmations devenues fausses sont supprimées : PublicNode sans credential, smoke unary Mainnet, Testnet non confirmé/non versionné et gate `pre.013` encore pending.
|
||||||
|
|
||||||
|
## 7. Frontière avec `pre.015`
|
||||||
|
|
||||||
|
Cette tranche ne touche pas :
|
||||||
|
|
||||||
|
```text
|
||||||
|
prompts/015-V0_2_10_START_PROMPT.md
|
||||||
|
CHANGELOG.md
|
||||||
|
ROADMAP.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Ces trois surfaces appartiennent exclusivement à `pre.015`, hors `Cargo.toml` et son delta mécanique.
|
||||||
|
|
||||||
|
Si un défaut de code, smoke, Config ou autre document durable est découvert après le gate de `pre.014`, il ne doit pas être glissé dans `pre.015` : une nouvelle prerelease du couloir approprié doit être ouverte conformément aux règles de fermeture.
|
||||||
|
|
||||||
|
## 8. Fichiers modifiés/ajoutés
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cargo.toml
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md
|
||||||
|
docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md
|
||||||
|
crates/ksp-onchain-transport-lib/README.md
|
||||||
|
crates/ksp-onchain-transport-lib/USAGE.md
|
||||||
|
deltas/0.2.9/pre.014.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. Gate opérateur
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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.2.9
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets
|
||||||
|
cargo test --workspace
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun smoke live ni `cargo tree` n'est à rejouer dans `pre.014` si le delta est appliqué exactement : aucune surface technique ou dépendance n'est modifiée.
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,9 +1,9 @@
|
|||||||
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
|
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
|
||||||
<!-- version: 24 -->
|
<!-- version: 25 -->
|
||||||
|
|
||||||
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
|
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
|
||||||
|
|
||||||
**Statut courant : `0.2.9-pre.012` a passé son gate déterministe local sans warning ; le smoke PublicNode live et les graphes Cargo finaux n'ont pas été exécutés dans le log opérateur fourni. `pre.012-fix.001` introduit une règle durable de séparation des dernières prereleases et recalibre la fermeture : `pre.013` technique/live, `pre.014` réconciliation documentaire, `pre.015` préparation de publication minimale, puis `rel.001`.**
|
**Statut courant : le couloir technique `0.2.9-pre.013` est fermé par `pre.013-fix.004` : gates déterministes et workspace verts, graphes Cargo finaux inspectés, et smoke Yellowstone PublicNode authentifié exécuté avec succès sur Mainnet et Testnet (`2/2 PASS`). `pre.014` est la réconciliation documentaire finale ; seule `pre.015` restera ensuite pour le prompt `0.2.10`, `CHANGELOG.md` et `ROADMAP.md`, avant `rel.001`.**
|
||||||
|
|
||||||
## 1. Objet et autorité de la release
|
## 1. Objet et autorité de la release
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ aucune promesse exactly-once/lossless non prouvée
|
|||||||
Config Transport V3 backward-readable V1/V2
|
Config Transport V3 backward-readable V1/V2
|
||||||
provider et protocol distincts dans Config
|
provider et protocol distincts dans Config
|
||||||
première intégration PublicNode strictement standard
|
première intégration PublicNode strictement standard
|
||||||
smoke live opt-in sans credential versionné
|
smoke live opt-in avec credential secret non versionné
|
||||||
non-régressions HTTP, WebSocket standard et Helius WebSocket
|
non-régressions HTTP, WebSocket standard et Helius WebSocket
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ https://docs.rs/crate/yellowstone-grpc-proto/latest
|
|||||||
https://docs.rs/crate/yellowstone-grpc-client/latest
|
https://docs.rs/crate/yellowstone-grpc-client/latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Une réaudite finale est requise en `pre.012` si l'upstream a changé matériellement pendant la release.
|
Le réaudit final a été exécuté en `pre.012`; aucun changement upstream matériel n’a remis en cause la surface retenue.
|
||||||
|
|
||||||
### 4.2 Licence
|
### 4.2 Licence
|
||||||
|
|
||||||
@@ -514,42 +514,43 @@ Le tuple historique n'est pas modifié silencieusement.
|
|||||||
|
|
||||||
### 9.1 Mainnet
|
### 9.1 Mainnet
|
||||||
|
|
||||||
La surface publique réauditée le 2026-08-24 confirme Yellowstone gRPC Solana Mainnet et affiche le host/port :
|
Endpoint retenu et validé en live :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
solana-yellowstone-grpc.publicnode.com:443
|
https://solana-yellowstone-grpc.publicnode.com:443
|
||||||
```
|
```
|
||||||
|
|
||||||
Le wrapper KSP attend une URL `http/https`; Config matérialise donc le même endpoint TLS sous la forme `https://solana-yellowstone-grpc.publicnode.com:443`.
|
Le profil committé est :
|
||||||
|
|
||||||
`pre.011` versionne donc un profil :
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
profile_id = publicnode_mainnet
|
profile_id = publicnode_mainnet
|
||||||
provider = publicnode
|
provider = publicnode
|
||||||
cluster = mainnet-beta
|
cluster = mainnet-beta
|
||||||
protocol = solana_yellowstone
|
protocol = solana_yellowstone
|
||||||
credential = aucun
|
metadata = x-token secret via KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN
|
||||||
```
|
```
|
||||||
|
|
||||||
La partie HTTP/WS de ce profil reste standard Solana ; seul l'endpoint gRPC est PublicNode.
|
Les tentatives sans metadata ont atteint le service mais ont reçu `PERMISSION_DENIED`. Le profil final fournit donc le personal token PublicNode comme metadata gRPC secrète `x-token`; Transport ne connaît ni le nom de variable KSP ni sa provenance.
|
||||||
|
|
||||||
### 9.2 Testnet
|
### 9.2 Testnet
|
||||||
|
|
||||||
Le réaudit final du 2026-08-24 confirme que PublicNode annonce bien une capacité Solana Testnet gRPC. La surface officielle consultable ne fournit cependant toujours pas un hostname Testnet exact suffisamment autoritatif pour être versionné.
|
L'endpoint exact confirmé par l'opérateur et validé en live est :
|
||||||
|
|
||||||
Décision finale `0.2.9` :
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
existence Testnet gRPC confirmée
|
https://solana-testnet-yellowstone-grpc.publicnode.com:443
|
||||||
hostname Testnet exact non obtenu depuis une source autoritative
|
|
||||||
hostname déduit ou tiers interdit
|
|
||||||
profil Testnet committé non
|
|
||||||
smoke Testnet non
|
|
||||||
statut EXTERNAL BLOCK documentaire / NOT GUESSED
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Ce bloc externe ne remet pas en cause la fondation Mainnet. Une release provider ultérieure peut matérialiser Testnet dès qu'une source PublicNode autoritative expose l'endpoint exact.
|
Le profil committé est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
profile_id = publicnode_testnet
|
||||||
|
provider = publicnode
|
||||||
|
cluster = testnet
|
||||||
|
protocol = solana_yellowstone
|
||||||
|
metadata = x-token secret via KSP_SECRET_PUBLICNODE_TESTNET_GRPC_X_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
Le smoke final prouve qu'un même personal token opérateur peut fonctionner sur Mainnet et Testnet. KSP conserve néanmoins deux variables de configuration distinctes afin de ne pas imposer une hypothèse de portée provider à long terme ; elles peuvent recevoir la même valeur. Cette séparation est une liberté de configuration KSP, pas une assertion que PublicNode délivre des tokens network-scoped.
|
||||||
|
|
||||||
## 10. Threat model et bornes
|
## 10. Threat model et bornes
|
||||||
|
|
||||||
@@ -589,14 +590,14 @@ Config sensitivity gate avant construction de metadata secret
|
|||||||
Ordre de preuve :
|
Ordre de preuve :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Transport programmatic -> PublicNode Mainnet Yellowstone
|
Transport programmatic -> PublicNode Mainnet Yellowstone + secret x-token fourni au harness
|
||||||
Transport programmatic -> PublicNode Testnet seulement si endpoint exact confirmé
|
Transport programmatic -> PublicNode Testnet Yellowstone + secret x-token fourni au harness
|
||||||
Config V3 -> Transport -> PublicNode via composition légitime, jamais un smoke réseau placé dans Config par facilité
|
Config V3 -> Transport -> PublicNode via secret_metadata, jamais un smoke réseau placé dans Config par facilité
|
||||||
```
|
```
|
||||||
|
|
||||||
Un smoke Transport pur peut vivre dans `ksp-onchain-transport-lib/tests` puisqu'il construit ses settings programmatiquement.
|
Un smoke Transport pur peut vivre dans `ksp-onchain-transport-lib/tests` puisqu'il construit ses settings programmatiquement.
|
||||||
|
|
||||||
Un smoke cross-crates Config -> Transport ne doit pas devenir une responsabilité durable de `ksp-config-lib`. S'il n'existe pas encore de surface d'intégration appropriée, la procédure reste opérateur/documentée en `pre.012`.
|
Un smoke cross-crates Config -> Transport ne doit pas devenir une responsabilité durable de `ksp-config-lib`. S’il n’existe pas encore de surface d’intégration appropriée, la preuve live reste un smoke Transport programmatique avec secret fourni uniquement au harness opérateur.
|
||||||
|
|
||||||
Aucun secret provider n'est versionné.
|
Aucun secret provider n'est versionné.
|
||||||
|
|
||||||
@@ -604,24 +605,24 @@ Aucun secret provider n'est versionné.
|
|||||||
|
|
||||||
Les preuves détaillées restent dans les fichiers `deltas/0.2.9/*.md`. Le plan ne duplique plus leurs journaux complets.
|
Les preuves détaillées restent dans les fichiers `deltas/0.2.9/*.md`. Le plan ne duplique plus leurs journaux complets.
|
||||||
|
|
||||||
| Tranche | Objet | État consolidé |
|
| Tranche | Objet | État consolidé |
|
||||||
|-------------------|----------------------------------------------------------|----------------------------|
|
|-------------------|----------------------------------------------------------|----------------------|
|
||||||
| `pre.001` + fixes | audit upstream, licence, providers, architecture, sizing | **CLOSED** |
|
| `pre.001` + fixes | audit upstream, licence, providers, architecture, sizing | **CLOSED** |
|
||||||
| `pre.002` + fixes | dépendances, settings/errors, channel minimal | **CLOSED** |
|
| `pre.002` + fixes | dépendances, settings/errors, channel minimal | **CLOSED** |
|
||||||
| `pre.003` + fix | TLS, metadata, fixture locale, 7 unary | **CLOSED** |
|
| `pre.003` + fix | TLS, metadata, fixture locale, 7 unary | **CLOSED** |
|
||||||
| `pre.004` + fix | Subscribe foundation/common | **CLOSED** |
|
| `pre.004` + fix | Subscribe foundation/common | **CLOSED** |
|
||||||
| `pre.005` + fix | Accounts + Slots | **CLOSED** |
|
| `pre.005` + fix | Accounts + Slots | **CLOSED** |
|
||||||
| `pre.006` | namespace privé HTTP explicite | **CLOSED** |
|
| `pre.006` | namespace privé HTTP explicite | **CLOSED** |
|
||||||
| `pre.007` | Transactions + transaction_status | **CLOSED** |
|
| `pre.007` | Transactions + transaction_status | **CLOSED** |
|
||||||
| `pre.008` + fix | Blocks + block_meta + entry | **CLOSED** |
|
| `pre.008` + fix | Blocks + block_meta + entry | **CLOSED** |
|
||||||
| `pre.009` + fix | bidi, Ping/Pong, backpressure, half-close, shutdown | **CLOSED** |
|
| `pre.009` + fix | bidi, Ping/Pong, backpressure, half-close, shutdown | **CLOSED** |
|
||||||
| `pre.010` + fix | reconnect, from_slot, ReplayInfo, gaps/duplicates | **CLOSED** |
|
| `pre.010` + fix | reconnect, from_slot, ReplayInfo, gaps/duplicates | **CLOSED** |
|
||||||
| `pre.011` | Config V3 + protocol/provider + PublicNode Mainnet | **CLOSED** |
|
| `pre.011` | Config V3 + protocol/provider + PublicNode Mainnet | **CLOSED** |
|
||||||
| `pre.012` | réaudit + smoke ajouté + docs préparatoires | **LOCAL GATE PASS** |
|
| `pre.012` | réaudit + smoke ajouté + docs préparatoires | **LOCAL GATE PASS** |
|
||||||
| `pre.012-fix.001` | règles de séparation de fermeture + recalibrage | **ACTIVE DOCUMENTARY FIX** |
|
| `pre.012-fix.001` | règles de séparation de fermeture + recalibrage | **CLOSED** |
|
||||||
| `pre.013` | gate technique/live PublicNode + graphes finaux | **PLANNED** |
|
| `pre.013` + fixes | gate technique/live PublicNode + graphes finaux | **CLOSED** |
|
||||||
| `pre.014` | réconciliation documentaire finale | **PLANNED** |
|
| `pre.014` | réconciliation documentaire finale | **ACTIVE CANDIDATE** |
|
||||||
| `pre.015` | prompt + CHANGELOG + ROADMAP | **PLANNED** |
|
| `pre.015` | prompt + CHANGELOG + ROADMAP | **PLANNED** |
|
||||||
|
|
||||||
Gate opérateur déterministe de `pre.012` reçu le 2026-08-24 :
|
Gate opérateur déterministe de `pre.012` reçu le 2026-08-24 :
|
||||||
|
|
||||||
@@ -643,34 +644,50 @@ PublicNode live smoke NOT RUN, test ignored
|
|||||||
cargo tree final NOT PROVIDED / NOT RUN in supplied log
|
cargo tree final NOT PROVIDED / NOT RUN in supplied log
|
||||||
```
|
```
|
||||||
|
|
||||||
`pre.012` reste historiquement une tranche mixte créée avant l'adoption de la nouvelle règle. Son fix ne réécrit pas cette histoire : le prompt `0.2.10` déjà présent est désormais considéré comme un brouillon à finaliser seulement en `pre.015`, et les README/USAGE préparés seront réconciliés en `pre.014`.
|
`pre.012` reste historiquement une tranche mixte créée avant l'adoption de la nouvelle règle. Son fix ne réécrit pas cette histoire : le prompt `0.2.10` déjà présent est désormais considéré comme un brouillon à finaliser seulement en `pre.015`, et les README/USAGE préparés sont réconciliés par la présente `pre.014`.
|
||||||
|
|
||||||
|
Gate technique final `pre.013-fix.004` reçu le 2026-08-24 :
|
||||||
|
|
||||||
|
```text
|
||||||
|
fmt/audit Rust PASS sans warning
|
||||||
|
Markdown tables PASS, 87 tableaux / 258 fichiers
|
||||||
|
cargo check PASS
|
||||||
|
cargo clippy --all-targets PASS sans warning
|
||||||
|
Transport unit 383/383
|
||||||
|
Transport public API 49/49
|
||||||
|
Transport completeness 43/43
|
||||||
|
Transport doctests 4/4
|
||||||
|
cargo test --workspace PASS
|
||||||
|
cargo graphs finaux inspectés, stack Yellowstone unique tonic/prost 0.14
|
||||||
|
PublicNode Mainnet Subscribe + slot PASS
|
||||||
|
PublicNode Testnet Subscribe + slot PASS
|
||||||
|
live smoke total 2/2 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Les graphes inspectés avant `fix.004` restent valides : ce fix n'a modifié ni dépendance ni feature Cargo. La stack Yellowstone résolue est `yellowstone-grpc-proto 12.6.0`, `tonic/tonic-prost 0.14.6`, `prost/prost-types 0.14.4`, sans `yellowstone-grpc-client` runtime.
|
||||||
|
|
||||||
## 13. Forecast restant recalibré
|
## 13. Forecast restant recalibré
|
||||||
|
|
||||||
### `pre.013` — gate technique/live final
|
### `pre.013` — gate technique/live final — **CLOSED**
|
||||||
|
|
||||||
Payload autorisé :
|
Le couloir technique a finalement nécessité quatre fixes : découverte de l'auth PublicNode, ajout Testnet, adaptation de la fermeture live, puis conformité Clippy du harness. Le résultat consolidé est :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
workspace.package.version = 0.2.9-pre.13
|
workspace.package.version final du couloir = 0.2.9-pre.13.fix.4
|
||||||
exécution du smoke PublicNode Mainnet déjà versionné
|
PublicNode Mainnet Subscribe + slot PASS
|
||||||
cargo tree Transport direct
|
PublicNode Testnet Subscribe + slot PASS
|
||||||
cargo tree Transport --duplicates
|
secret wire metadata x-token
|
||||||
cargo tree --duplicates
|
secret versionné non
|
||||||
constat factuel de tout incident réseau/provider/TLS
|
harness deux lignes stdin, valeurs identiques autorisées
|
||||||
aucune réconciliation README/USAGE
|
close provider succès ou timeout KSP borné après slot reçu
|
||||||
aucune finalisation prompt/CHANGELOG/ROADMAP
|
graphes Cargo inspectés
|
||||||
|
clippy --all-targets PASS sans warning
|
||||||
|
workspace PASS
|
||||||
```
|
```
|
||||||
|
|
||||||
Commande live centrale :
|
Les essais intermédiaires `PERMISSION_DENIED` sans credential sont conservés dans les deltas `pre.013-fix.001` à `fix.003`; ils ne sont pas réinterprétés comme une régression du moteur standard.
|
||||||
|
|
||||||
```bash
|
### `pre.014` — réconciliation documentaire finale — **ACTIVE CANDIDATE**
|
||||||
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
|
|
||||||
```
|
|
||||||
|
|
||||||
Un échec local du smoke est corrigé dans `pre.013-fix.NNN`. Un incident externe est documenté comme tel. Un fix de `pre.013` ne contient pas de correction documentaire de clôture.
|
|
||||||
|
|
||||||
### `pre.014` — réconciliation documentaire finale
|
|
||||||
|
|
||||||
Payload :
|
Payload :
|
||||||
|
|
||||||
@@ -724,20 +741,7 @@ moteur Yellowstone + façade Solana standard + Config provider-neutral + premiè
|
|||||||
|
|
||||||
## 15. Gates opérateur restants
|
## 15. Gates opérateur restants
|
||||||
|
|
||||||
Gate `pre.013` :
|
Le gate `pre.013` est fermé. Gate `pre.014` :
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo fmt --all
|
|
||||||
python3 scripts/audit_rust_workspace_rules.py
|
|
||||||
cargo check --workspace
|
|
||||||
cargo clippy --workspace --all-targets
|
|
||||||
cargo tree -p ksp-onchain-transport-lib
|
|
||||||
cargo tree -p ksp-onchain-transport-lib --duplicates
|
|
||||||
cargo tree --duplicates
|
|
||||||
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
|
|
||||||
```
|
|
||||||
|
|
||||||
Gate `pre.014` :
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.9
|
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.9
|
||||||
@@ -760,8 +764,9 @@ bounds/backpressure/shutdown verts
|
|||||||
reconnect/replay documentés sans lossless implicite
|
reconnect/replay documentés sans lossless implicite
|
||||||
Config V3 backward V1/V2
|
Config V3 backward V1/V2
|
||||||
provider/protocol distincts
|
provider/protocol distincts
|
||||||
PublicNode Mainnet live exécuté avec résultat consigné
|
PublicNode Mainnet live Subscribe + slot PASS
|
||||||
Testnet reporté factuellement si endpoint exact non confirmé
|
PublicNode Testnet live Subscribe + slot PASS
|
||||||
|
auth PublicNode x-token secret documentée sans secret versionné
|
||||||
HTTP 52+14 non régressé
|
HTTP 52+14 non régressé
|
||||||
Standard WS 18/18 non régressé
|
Standard WS 18/18 non régressé
|
||||||
Helius WS non régressé
|
Helius WS non régressé
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<!-- file: docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md -->
|
<!-- file: docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md -->
|
||||||
<!-- version: 26 -->
|
<!-- version: 27 -->
|
||||||
|
|
||||||
# Validation `0.2.9` — Yellowstone gRPC standard + PublicNode
|
# Validation `0.2.9` — Yellowstone gRPC standard + PublicNode
|
||||||
|
|
||||||
**Statut courant : le gate déterministe de `pre.012` est vert sans warning ; le smoke PublicNode live et les graphes Cargo finaux ne figurent pas comme exécutés dans le log opérateur fourni. `pre.012-fix.001` ajoute la règle durable de séparation de fermeture et déplace les gates restants vers `pre.013` technique/live, `pre.014` réconciliation documentaire et `pre.015` publication minimale.**
|
**Statut courant : la validation technique `pre.013-fix.004` est fermée et verte : `clippy --all-targets`, workspace, graphes Cargo, puis smoke PublicNode authentifié Mainnet + Testnet `2/2 PASS`. `pre.014` réconcilie et ferme cette matrice documentaire ; seule la tranche `pre.015` de préparation de publication restera avant `rel.001`.**
|
||||||
|
|
||||||
## 1. Autorités et baseline courante
|
## 1. Autorités et baseline courante
|
||||||
|
|
||||||
@@ -40,15 +40,15 @@ Cette baseline est le seuil de non-régression de `pre.012`.
|
|||||||
|
|
||||||
## 2. Gate dépendances et licence
|
## 2. Gate dépendances et licence
|
||||||
|
|
||||||
| Exigence | Décision / preuve | État |
|
| Exigence | Décision / preuve | État |
|
||||||
|--------------------------------|------------------------------------------|-------------------|
|
|--------------------------------|------------------------------------------|----------|
|
||||||
| proto officiel sans vendoring | `yellowstone-grpc-proto ^12.6` | **PASS** |
|
| proto officiel sans vendoring | `yellowstone-grpc-proto ^12.6` | **PASS** |
|
||||||
| pas de client upstream runtime | `yellowstone-grpc-client` absent | **PASS** |
|
| pas de client upstream runtime | `yellowstone-grpc-client` absent | **PASS** |
|
||||||
| runtime Tonic KSP-owned | `tonic ^0.14` + `tonic-prost ^0.14` | **PASS** |
|
| runtime Tonic KSP-owned | `tonic ^0.14` + `tonic-prost ^0.14` | **PASS** |
|
||||||
| proto subtree compatible | Apache-2.0 selon `LICENSING.md` upstream | **PASS** |
|
| proto subtree compatible | Apache-2.0 selon `LICENSING.md` upstream | **PASS** |
|
||||||
| source AGPL copiée | aucune | **PASS** |
|
| source AGPL copiée | aucune | **PASS** |
|
||||||
| raw client Tonic public | aucun | **PASS** |
|
| raw client Tonic public | aucun | **PASS** |
|
||||||
| graph final | réinspection `pre.012` | **PENDING FINAL** |
|
| graph final | graphes `pre.013` inspectés | **PASS** |
|
||||||
|
|
||||||
Le graphe de dépendances n'est pas modifié par `pre.012`; aucune nouvelle dépendance Cargo n'est introduite dans cette tranche.
|
Le graphe de dépendances n'est pas modifié par `pre.012`; aucune nouvelle dépendance Cargo n'est introduite dans cette tranche.
|
||||||
|
|
||||||
@@ -276,30 +276,33 @@ Les tests V3 démontrent le cas valide et les deux croisements invalides sans ex
|
|||||||
Profil committé et validé :
|
Profil committé et validé :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
profile_id = publicnode_mainnet
|
profile_id = publicnode_mainnet
|
||||||
provider = publicnode
|
provider = publicnode
|
||||||
cluster = mainnet-beta
|
cluster = mainnet-beta
|
||||||
protocol = solana_yellowstone
|
protocol = solana_yellowstone
|
||||||
url = https://solana-yellowstone-grpc.publicnode.com:443 # provider affiche host:port ; KSP ajoute le scheme TLS requis
|
url = https://solana-yellowstone-grpc.publicnode.com:443
|
||||||
metadata = aucune
|
secret_metadata = x-token <- ${KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN}
|
||||||
```
|
```
|
||||||
|
|
||||||
Le mapping produit un endpoint TLS Yellowstone standard ; le test `committed_v3_publicnode_mainnet_maps_provider_neutral_yellowstone_grpc` passe et `Debug` ne doit pas exposer l'URL.
|
Le mapping produit un endpoint TLS Yellowstone standard et une metadata secrète redacted. Le smoke final ouvre `Subscribe`, reçoit un update `Slot` non nul et ferme de manière bornée : **PASS**.
|
||||||
|
|
||||||
### 8.5 PublicNode Testnet
|
### 8.5 PublicNode Testnet
|
||||||
|
|
||||||
Verdict final documentaire : **EXTERNAL BLOCK, NOT GUESSED**.
|
Profil committé et validé :
|
||||||
|
|
||||||
Le réaudit officiel du 2026-08-24 confirme une capacité Solana Testnet gRPC chez PublicNode, mais l'hostname exact n'a pas été obtenu depuis une source PublicNode suffisamment autoritative. Aucun profil, aucun hostname déduit et aucun smoke Testnet ne sont versionnés.
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
capacité Testnet gRPC confirmée
|
profile_id = publicnode_testnet
|
||||||
hostname exact non confirmé
|
provider = publicnode
|
||||||
profil KSP absent
|
cluster = testnet
|
||||||
smoke KSP absent
|
protocol = solana_yellowstone
|
||||||
raison interdiction d'inventer un endpoint provider
|
url = https://solana-testnet-yellowstone-grpc.publicnode.com:443
|
||||||
|
secret_metadata = x-token <- ${KSP_SECRET_PUBLICNODE_TESTNET_GRPC_X_TOKEN}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Le hostname exact a été fourni par l'opérateur puis validé par le smoke live. `Subscribe` reçoit un update `Slot` non nul : **PASS**.
|
||||||
|
|
||||||
|
Le même personal token opérateur a été validé sur les deux réseaux. Les deux variables KSP restent distinctes afin de permettre des valeurs différentes si la policy provider change ; cette modélisation ne constitue pas une preuve que les tokens PublicNode sont network-scoped.
|
||||||
|
|
||||||
## 9. Provider-neutrality
|
## 9. Provider-neutrality
|
||||||
|
|
||||||
| Point | Verdict |
|
| Point | Verdict |
|
||||||
@@ -326,107 +329,96 @@ Transport -> std::env KSP_* interdit
|
|||||||
tracing direct Transport interdit
|
tracing direct Transport interdit
|
||||||
```
|
```
|
||||||
|
|
||||||
`pre.012` ne modifie pas le runtime Transport ; elle ajoute uniquement un smoke live ignoré par défaut et de la documentation/audit. Son seuil de non-régression est la baseline `pre.011`.
|
La baseline `pre.011` reste conservée. Les changements `pre.013` ont porté uniquement le gate live, la Config PublicNode/Testnet et le harness de smoke ; le gate final `pre.013-fix.004` confirme les non-régressions workspace.
|
||||||
|
|
||||||
## 11. Historique des gates fermé
|
## 11. Historique des gates fermé
|
||||||
|
|
||||||
Les détails de commandes, warnings corrigés et fichiers exacts restent dans leurs deltas immuables.
|
Les détails de commandes, warnings corrigés et fichiers exacts restent dans leurs deltas immuables.
|
||||||
|
|
||||||
| Tranche | Gate consolidé |
|
| Tranche | Gate consolidé |
|
||||||
|-----------------------------------|--------------------------------------|
|
|-----------------------------------|---------------------------------------|
|
||||||
| `pre.001` + `fix.001` + `fix.002` | audit/sizing/providers/licence fermé |
|
| `pre.001` + `fix.001` + `fix.002` | audit/sizing/providers/licence fermé |
|
||||||
| `pre.002` + `fix.001` + `fix.002` | moteur/settings/channel fermé |
|
| `pre.002` + `fix.001` + `fix.002` | moteur/settings/channel fermé |
|
||||||
| `pre.003` + `fix.001` | TLS/metadata/unary fermé |
|
| `pre.003` + `fix.001` | TLS/metadata/unary fermé |
|
||||||
| `pre.004` + `fix.001` | Subscribe common fermé |
|
| `pre.004` + `fix.001` | Subscribe common fermé |
|
||||||
| `pre.005` + `fix.001` | Accounts/Slots fermé |
|
| `pre.005` + `fix.001` | Accounts/Slots fermé |
|
||||||
| `pre.006` | namespace HTTP fermé |
|
| `pre.006` | namespace HTTP fermé |
|
||||||
| `pre.007` | Transactions fermé |
|
| `pre.007` | Transactions fermé |
|
||||||
| `pre.008` + `fix.001` | Blocks fermé |
|
| `pre.008` + `fix.001` | Blocks fermé |
|
||||||
| `pre.009` + `fix.001` | bidi/backpressure fermé |
|
| `pre.009` + `fix.001` | bidi/backpressure fermé |
|
||||||
| `pre.010` + `fix.001` | reconnect/replay fermé sans warning |
|
| `pre.010` + `fix.001` | reconnect/replay fermé sans warning |
|
||||||
| `pre.011` | Config V3/PublicNode mapping fermé |
|
| `pre.011` | Config V3/PublicNode mapping fermé |
|
||||||
|
| `pre.012` + `fix.001` | réaudit + règles de fermeture |
|
||||||
|
| `pre.013` + `fix.001`–`fix.004` | live PublicNode + graphes fermé |
|
||||||
|
| `pre.014` | réconciliation documentaire candidate |
|
||||||
|
|
||||||
Cette table remplace les anciens appendices numérotés successivement `19.x`, `20`, `21`, etc. qui rendaient le document ambigu.
|
Cette table remplace les anciens appendices numérotés successivement `19.x`, `20`, `21`, etc. qui rendaient le document ambigu.
|
||||||
|
|
||||||
## 12. Verdict opérateur `pre.012`
|
## 12. Verdict opérateur consolidé jusqu'à `pre.013-fix.004`
|
||||||
|
|
||||||
### 12.1 Gate déterministe reçu
|
Le gate technique final reçu le 2026-08-24 est :
|
||||||
|
|
||||||
| Exigence | Résultat opérateur |
|
| Exigence | Résultat opérateur |
|
||||||
|----------------------------------------------|--------------------------------------|
|
|-----------------------------------------------|--------------------------------------|
|
||||||
| `cargo fmt --all` | **PASS** |
|
| `cargo fmt --all` | **PASS** |
|
||||||
| audit Rust workspace | **PASS, 0 candidate export** |
|
| audit Rust workspace | **PASS, 0 candidate export** |
|
||||||
| audit Markdown | **PASS, 87 tableaux / 252 fichiers** |
|
| audit Markdown | **PASS, 87 tableaux / 258 fichiers** |
|
||||||
| `cargo check --workspace` | **PASS** |
|
| `cargo check --workspace` | **PASS** |
|
||||||
| `cargo clippy --workspace --all-targets` | **PASS sans warning** |
|
| `cargo clippy --workspace --all-targets` | **PASS sans warning** |
|
||||||
| Config unit | **113/113 PASS** |
|
| Transport unit | **383/383 PASS** |
|
||||||
| Config public API | **15/15 PASS** |
|
| Transport public API | **49/49 PASS** |
|
||||||
| Config ownership | **5/5 PASS** |
|
| Transport release completeness | **43/43 PASS** |
|
||||||
| Transport unit | **383/383 PASS** |
|
| Transport doctests | **4/4 PASS** |
|
||||||
| Transport public API | **49/49 PASS** |
|
| Config unit dans workspace | **113/113 PASS** |
|
||||||
| Transport release completeness | **43/43 PASS** |
|
| Config ownership dans workspace | **5/5 PASS** |
|
||||||
| Transport doctests | **4/4 PASS** |
|
| Config public API dans workspace | **15/15 PASS** |
|
||||||
| workspace dependencies | **3/3 PASS** |
|
| workspace dependencies | **3/3 PASS** |
|
||||||
| `cargo test --workspace` | **PASS** |
|
| `cargo test --workspace` | **PASS** |
|
||||||
| smoke Mainnet programmatique sans credential | **NOT RUN, ignored** |
|
| graphes Cargo finaux | **PASS / inspectés** |
|
||||||
| graphes Cargo finaux | **NOT PROVIDED / NOT RUN** |
|
| smoke PublicNode Mainnet `Subscribe` + `Slot` | **PASS** |
|
||||||
|
| smoke PublicNode Testnet `Subscribe` + `Slot` | **PASS** |
|
||||||
|
| smoke live total | **2/2 PASS** |
|
||||||
|
|
||||||
Le test `yellowstone_publicnode_smoke` compile et apparaît correctement comme `ignored` dans les tests Transport et workspace, mais cela ne constitue pas une exécution live. Aucune preuve de `cargo tree` final n'est présente dans le log fourni.
|
Les graphes résolus confirment la stack attendue :
|
||||||
|
|
||||||
### 12.2 Effet de `pre.012-fix.001`
|
|
||||||
|
|
||||||
Le fix ne change ni runtime, ni schema, ni Config, ni smoke. Il corrige le workflow de fermeture afin que les responsabilités restantes ne soient plus mélangées :
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
pre.013 technique/live : smoke PublicNode + graphes Cargo finaux
|
yellowstone-grpc-proto 12.6.0
|
||||||
pre.014 réconciliation documentaire : plan/validation/README/USAGE/références
|
tonic 0.14.6
|
||||||
pre.015 publication minimale : prompt suivant + CHANGELOG + ROADMAP
|
tonic-prost 0.14.6
|
||||||
rel.001 mécanique stable uniquement
|
prost 0.14.4
|
||||||
|
prost-types 0.14.4
|
||||||
|
yellowstone-grpc-client absent du runtime KSP
|
||||||
```
|
```
|
||||||
|
|
||||||
Le contenu prompt/README/USAGE déjà préparé en `pre.012` n'est pas supprimé rétroactivement. Le prompt reste un brouillon jusqu'à `pre.015` ; README/USAGE seront réconciliés définitivement en `pre.014`.
|
Les graphes ont été exécutés avant `pre.013-fix.004`; ils restent valides car `fix.004` n'a modifié ni dépendance ni feature Cargo.
|
||||||
|
|
||||||
## 13. Gate `pre.013` — technique/live
|
## 13. Verdict PublicNode live final
|
||||||
|
|
||||||
Commandes minimales :
|
Les essais intermédiaires ont établi deux faits utiles : les appels sans credential peuvent atteindre le service mais recevoir `PERMISSION_DENIED`, et la validation représentative de la foundation doit porter sur `Subscribe` plutôt que sur une unary provider éventuellement restreinte.
|
||||||
|
|
||||||
```bash
|
Le smoke final :
|
||||||
cargo fmt --all
|
|
||||||
python3 scripts/audit_rust_workspace_rules.py
|
|
||||||
cargo check --workspace
|
|
||||||
cargo clippy --workspace --all-targets
|
|
||||||
cargo tree -p ksp-onchain-transport-lib
|
|
||||||
cargo tree -p ksp-onchain-transport-lib --duplicates
|
|
||||||
cargo tree --duplicates
|
|
||||||
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
|
|
||||||
```
|
|
||||||
|
|
||||||
Verdicts attendus :
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
smoke Mainnet réellement exécuté
|
reçoit deux personal tokens par stdin, Mainnet puis Testnet
|
||||||
GetVersion + GetSlot via TLS sans credential ou incident externe précisément classifié
|
accepte que les deux lignes contiennent la même valeur
|
||||||
graphes Cargo inspectés
|
construit une metadata secrète x-token
|
||||||
aucun changement README/USAGE/prompt/CHANGELOG/ROADMAP
|
ouvre TLS puis Subscribe
|
||||||
|
filtre slots
|
||||||
|
attend un YellowstoneSubscribeUpdate::Slot sous timeout
|
||||||
|
exige slot > 0
|
||||||
|
ferme de manière bornée
|
||||||
|
n'expose aucun secret dans URL/Debug/arguments
|
||||||
```
|
```
|
||||||
|
|
||||||
Un défaut local découvert dans ce gate reste dans `pre.013-fix.NNN`. Un incident externe n'est jamais maquillé en PASS local.
|
Résultat opérateur final : **Mainnet PASS, Testnet PASS, 2/2**.
|
||||||
|
|
||||||
|
Le timeout KSP de half-close est un résultat accepté par le harness uniquement après réception prouvée d'un slot ; le runtime conserve son contrat de timeout explicite.
|
||||||
|
|
||||||
## 14. Gate `pre.014` — réconciliation documentaire
|
## 14. Gate `pre.014` — réconciliation documentaire
|
||||||
|
|
||||||
Cette tranche ferme les documents durables après le gate technique réel :
|
Cette tranche ne modifie ni runtime, ni Config, ni schema, ni smoke. Elle synchronise le plan, la présente validation, README/USAGE Transport et les références durables avec les faits exécutés en `pre.013`.
|
||||||
|
|
||||||
```text
|
Le verdict technique de `0.2.9` est donc **PASS**. Après le gate documentaire `pre.014`, seuls le prompt suivant, `CHANGELOG.md` et `ROADMAP.md` restent à finaliser en `pre.015`.
|
||||||
plan 016
|
|
||||||
validation 012
|
|
||||||
README/USAGE Transport
|
|
||||||
documents de référence 0.2.9 réellement concernés
|
|
||||||
audit Markdown des documents touchés
|
|
||||||
```
|
|
||||||
|
|
||||||
Elle n'introduit aucun nouveau runtime/smoke et ne finalise pas `CHANGELOG.md`, `ROADMAP.md` ni le prompt suivant.
|
|
||||||
|
|
||||||
Le verdict de la validation 012 devient définitif dans cette tranche, sur la base exclusive des preuves réellement exécutées en `pre.013` et des gates antérieurs.
|
|
||||||
|
|
||||||
## 15. Gate `pre.015` — préparation de publication
|
## 15. Gate `pre.015` — préparation de publication
|
||||||
|
|
||||||
@@ -463,8 +455,9 @@ resource/backpressure/lifecycle verts
|
|||||||
reconnect/replay sans promesse lossless
|
reconnect/replay sans promesse lossless
|
||||||
Config V3 backward V1/V2
|
Config V3 backward V1/V2
|
||||||
provider/protocol distincts
|
provider/protocol distincts
|
||||||
PublicNode Mainnet live exécuté avec résultat consigné
|
PublicNode Mainnet live Subscribe + Slot PASS
|
||||||
Testnet jamais inventé
|
PublicNode Testnet live Subscribe + Slot PASS
|
||||||
|
x-token secret requis par les profils PublicNode, aucun secret versionné
|
||||||
HTTP/WS/Helius non régressés
|
HTTP/WS/Helius non régressés
|
||||||
dependency firewall vert
|
dependency firewall vert
|
||||||
cargo graphs inspectés
|
cargo graphs inspectés
|
||||||
|
|||||||
Reference in New Issue
Block a user