v0.2.9-pre.014

This commit is contained in:
2026-08-25 05:44:41 +02:00
parent dcabceb52f
commit 6ddf2b4995
7 changed files with 366 additions and 198 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-onchain-transport-lib/README.md -->
<!-- version: 21 -->
<!-- version: 22 -->
# `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 lobservabilité ; 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 nest pas versionné tant quune source officielle exploitable ne la pas confirmé ; KSP ne déduit pas un endpoint à partir dune 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 nest committé ni placé dans lURL. Le même token a été validé par lopérateur sur les deux réseaux, même si Config conserve deux variables distinctes pour laisser cette policy flexible.
## Résilience
@@ -300,15 +300,16 @@ Transport WebSocket pur : settings programmatiques -> WsSession
Composition historique : Config -> std.transport/devnet_public -> HttpTransportPool
-> getHealth/getGenesisHash/getVersion/getBalance
Transport Yellowstone gRPC : settings programmatiques -> PublicNode Mainnet
-> TLS -> GetVersion -> GetSlot confirmed
Transport Yellowstone gRPC : settings programmatiques + x-token secret
-> 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 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 nest committé en `0.2.8-pre.010`. Un tel test devrait à la fois obtenir `KSP_SECRET_HELIUS_API_KEY` via Config et exercer Transport ; lajouter dans Transport violerait lownership environnement/secret, tandis que lajouter dans Config étendrait lexception cross-crates que le projet veut au contraire résorber. La première surface KSP dinté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.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-onchain-transport-lib/USAGE.md -->
<!-- version: 21 -->
<!-- version: 22 -->
# Utilisation de `ksp-onchain-transport-lib`
@@ -270,14 +270,26 @@ let grpc_url = match ksp_onchain_transport_lib::YellowstoneGrpcEndpointUrl::pars
Ok(value) => value,
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",
true,
ksp_onchain_transport_lib::YellowstoneGrpcProviderName::new("publicnode"),
ksp_onchain_transport_lib::YellowstoneGrpcClusterName::new("mainnet-beta"),
grpc_url,
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 {
Ok(value) => value,
Err(error) => return Err(error),
@@ -289,7 +301,7 @@ let slot = grpc
.await;
```
LURL reste sensible : `Debug`, erreurs KSP et snapshots nen exposent pas la valeur. Les metadata publiques/secrètes se construisent avec `YellowstoneGrpcMetadataEntry`; Transport ne lit jamais lenvironnement.
LURL reste sensible : `Debug`, erreurs KSP et snapshots nen exposent pas la valeur. Les metadata publiques/secrètes se construisent avec `YellowstoneGrpcMetadataEntry`; Transport ne lit jamais lenvironnement. 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
@@ -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.
Le smoke **Transport Yellowstone gRPC PublicNode** ne dépend daucun secret ni de Config. Il construit lendpoint 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
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 nest pas versionné dans le smoke tant quune source PublicNode suffisamment autoritative et exploitable ne la 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 :