v0.2.9-pre.012
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-onchain-transport-lib/USAGE.md -->
|
||||
<!-- version: 20 -->
|
||||
<!-- version: 21 -->
|
||||
|
||||
# Utilisation de `ksp-onchain-transport-lib`
|
||||
|
||||
@@ -257,7 +257,99 @@ Les limites de taille et de capacité sont des policies KSP configurables par `W
|
||||
|
||||
Le snapshot expose seulement l'identité locale, les metadata logiques de l'endpoint, l'état, les compteurs sûrs et les projections locales de subscriptions. L'URL et les remote subscription IDs ne sont jamais projetés. La disparition de tous les handles de session déclenche le cleanup actor best-effort ; `close().await` reste la voie normale de shutdown.
|
||||
|
||||
## 4. Appels typés
|
||||
## 4. Yellowstone gRPC standard
|
||||
|
||||
### Construction programmatique et unary
|
||||
|
||||
Transport peut ouvrir directement un endpoint Yellowstone sans Config :
|
||||
|
||||
```rust
|
||||
let grpc_url = match ksp_onchain_transport_lib::YellowstoneGrpcEndpointUrl::parse(
|
||||
"https://solana-yellowstone-grpc.publicnode.com:443",
|
||||
) {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let grpc_endpoint = 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(),
|
||||
);
|
||||
let grpc_channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::connect(&grpc_endpoint).await {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let grpc = grpc_channel.standard_unary_client();
|
||||
let version = grpc.get_version().await;
|
||||
let slot = grpc
|
||||
.get_slot(Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed))
|
||||
.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.
|
||||
|
||||
### Config Transport V3
|
||||
|
||||
Avec `ksp-config-lib`, un profil V3 peut exposer les trois transports sans casser l’accesseur historique HTTP + WS :
|
||||
|
||||
```rust
|
||||
let resolved = match engine.load_resolved_transport_config(Some("publicnode_mainnet"), &environment) {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let grpc_settings = match resolved.grpc_settings() {
|
||||
Some(value) => value,
|
||||
None => return Err(ksp_core_lib::Error::new(
|
||||
ksp_onchain_transport_lib::ERROR_CODE_INVALID_SETTINGS,
|
||||
"selected profile has no Yellowstone gRPC endpoint",
|
||||
)),
|
||||
};
|
||||
let endpoint = match grpc_settings.endpoints().iter().find(|candidate| candidate.enabled()) {
|
||||
Some(value) => value,
|
||||
None => return Err(ksp_core_lib::Error::new(
|
||||
ksp_onchain_transport_lib::ERROR_CODE_INVALID_SETTINGS,
|
||||
"selected profile has no enabled Yellowstone gRPC endpoint",
|
||||
)),
|
||||
};
|
||||
let channel = ksp_onchain_transport_lib::YellowstoneGrpcChannel::connect(endpoint).await;
|
||||
```
|
||||
|
||||
`protocol = solana_yellowstone` est validé par Config et reste distinct du descripteur `provider`. Une valeur provider n’autorise pas Transport à introduire une API provider-specific sans divergence réelle.
|
||||
|
||||
### Subscribe bidirectionnel
|
||||
|
||||
Une session standard part d’une requête typed complète :
|
||||
|
||||
```rust
|
||||
let mut request = ksp_onchain_transport_lib::YellowstoneSubscribeRequest::new();
|
||||
let name = match ksp_onchain_transport_lib::YellowstoneSubscribeFilterName::new("slots") {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
if let Err(error) = request.insert_slot_filter(
|
||||
name,
|
||||
ksp_onchain_transport_lib::YellowstoneSubscribeSlotFilter::new(),
|
||||
) {
|
||||
return Err(error);
|
||||
}
|
||||
request.set_commitment(Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed));
|
||||
let mut stream = match grpc_channel.open_standard_subscribe(request).await {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let update = stream.next_update().await;
|
||||
let snapshot = stream.snapshot();
|
||||
let closed = stream.close().await;
|
||||
```
|
||||
|
||||
`try_update()` remplace dynamiquement la requête complète tant que la session est `Active`. Une mutation pendant `Reconnecting` est refusée pour éviter une application ambiguë. Le snapshot expose reconnects, replay attempts, gaps, duplicates, dernier `from_slot` demandé et dernier slot observé, sans endpoint ni payload arbitraire.
|
||||
|
||||
Le reconnect réutilise la dernière requête acceptée et peut avancer `from_slot`, mais le consumer doit traiter cette reprise comme best-effort. KSP ne promet ni exactly-once, ni replay historique complet, ni absence de fork/equivocation entre nœuds.
|
||||
|
||||
## 5. Appels typés
|
||||
|
||||
Les wrappers typés se trouvent directement sur `HttpTransportPool`.
|
||||
|
||||
@@ -317,7 +409,7 @@ let stake_minimum = pool.get_stake_minimum_delegation(&role, Some(&context)).awa
|
||||
|
||||
`getBlock` possède également une forme bare-encoding legacy séparée et deprecated. Les valeurs Economics restent celles du runtime : le consumer ne doit pas supposer localement un taux d'inflation ou un minimum de délégation constant.
|
||||
|
||||
## 5. Exécution JSON-RPC standard générique
|
||||
## 6. Exécution JSON-RPC standard générique
|
||||
|
||||
Une méthode courante auditée peut être appelée via son descriptor :
|
||||
|
||||
@@ -331,7 +423,7 @@ Cette API retourne un `serde_json::Value`. Elle reste utile pour les extensions
|
||||
|
||||
Avant exécution, `ensure_runtime_supported()` est appliqué. Une méthode historique `Removed` retourne `ERROR_CODE_METHOD_REMOVED` au lieu d'émettre un appel réseau fictif.
|
||||
|
||||
## 6. Sélection et admission sans exécuter la requête
|
||||
## 7. Sélection et admission sans exécuter la requête
|
||||
|
||||
Pour inspecter le routing :
|
||||
|
||||
@@ -346,13 +438,13 @@ Dans le même bloc, `acquire_for_method()` réserve réellement la capacité RPS
|
||||
|
||||
`HttpRequestPermit` détient la capacité de concurrence jusqu'à sa destruction. Aucun verrou synchrone n'est conservé pendant l'attente réseau.
|
||||
|
||||
## 7. Snapshots runtime
|
||||
## 8. Snapshots runtime
|
||||
|
||||
`HttpTransportPool::snapshot()` fournit une vue sûre des endpoints/rôles : disponibilité, limites, requêtes en vol, cooldown restant et compteurs runtime.
|
||||
|
||||
Les URLs d'endpoint n'y apparaissent jamais.
|
||||
|
||||
## 8. Retry et write submissions
|
||||
## 9. Retry et write submissions
|
||||
|
||||
La policy de retry est portée par la metadata des méthodes et `evaluate_transport_retry()`.
|
||||
|
||||
@@ -360,7 +452,7 @@ Les reads/simulations classés `RetrySafe` peuvent être réessayés dans le bud
|
||||
|
||||
Pour une opération `WriteSubmission / NeverAfterDispatch`, un timeout ou autre résultat ambigu après dispatch arrête la resoumission automatique. Le consumer métier ne doit pas contourner cette protection avec une boucle de retry externe aveugle.
|
||||
|
||||
## 9. Logging
|
||||
## 10. Logging
|
||||
|
||||
Les événements Transport utilisent le target :
|
||||
|
||||
@@ -372,7 +464,7 @@ Ne jamais journaliser l'URL complète, un token provider, un body massif, une tr
|
||||
|
||||
La configuration standard route les événements `info` de Transport vers un fichier dédié. Pour une investigation temporaire, élever uniquement ce target/sink à `debug` ou `trace`, puis revenir à `info` avant clôture du développement.
|
||||
|
||||
## 10. Smokes Devnet opt-in
|
||||
## 11. Smokes réseau opt-in
|
||||
|
||||
Le smoke **Transport HTTP pur** construit ses settings programmatiquement et exerce un sous-ensemble représentatif d'Accounts/Tokens/Cluster, trois reads Transactions, puis des reads Blocks/Economics :
|
||||
|
||||
@@ -390,6 +482,14 @@ 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 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` :
|
||||
|
||||
```bash
|
||||
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Le smoke de **composition Config -> Transport** reste également disponible :
|
||||
|
||||
```bash
|
||||
@@ -400,7 +500,7 @@ Il valide le profil committé `devnet_public` et les quatre canaris foundation.
|
||||
|
||||
### Smoke Helius live
|
||||
|
||||
Aucun nouveau test Helius live n’est committé en `0.2.8-pre.010`. La raison est architecturale : Transport ne peut pas lire `KSP_SECRET_HELIUS_API_KEY` ni dépendre de Config, et Config ne doit pas devenir la destination générale des futurs smokes `Config + autre crate`. Créer un quatrième smoke dans l’une de ces deux crates contournerait donc une frontière déjà documentée.
|
||||
Aucun nouveau test Helius live n’est committé en `0.2.8-pre.010`. La raison est architecturale : Transport ne peut pas lire `KSP_SECRET_HELIUS_API_KEY` ni dépendre de Config, et Config ne doit pas devenir la destination générale des futurs smokes `Config + autre crate`. Créer un smoke Helius supplémentaire dans l’une de ces deux crates contournerait donc une frontière déjà documentée.
|
||||
|
||||
Lorsque la surface KSP d’intégration/orchestration dédiée existera, le smoke live minimal recommandé sera :
|
||||
|
||||
@@ -416,7 +516,7 @@ Config helius_devnet
|
||||
|
||||
Ce scénario utilise une méthode standard stable sur l’endpoint Helius et teste donc auth + façade provider + actor + unsubscribe sans dépendre d’une entitlement particulière de `transactionSubscribe`. Un smoke `transactionSubscribe` pourra être ajouté séparément comme opt-in provider-specific si l’environnement opérateur possède les droits nécessaires ; il ne doit pas devenir un gate réseau obligatoire de la release.
|
||||
|
||||
Les endpoints publics/provider sont des dépendances externes. Un rate-limit, refus d’auth, entitlement absente ou incident réseau n’est pas assimilé automatiquement à une régression locale ; les fixtures HTTP/WebSocket locales et les gates déterministes restent autoritaires.
|
||||
Les endpoints publics/provider sont des dépendances externes. Un rate-limit, refus d’auth, entitlement absente ou incident réseau n’est pas assimilé automatiquement à une régression locale ; les fixtures HTTP/WebSocket/gRPC locales et les gates déterministes restent autoritaires.
|
||||
|
||||
Pour auditer les dépendances, inspecter également le graphe effectif après résolution Cargo :
|
||||
|
||||
|
||||
Reference in New Issue
Block a user