v0.2.9-pre.012
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<!-- file: crates/ksp-onchain-transport-lib/README.md -->
|
||||
<!-- version: 20 -->
|
||||
<!-- version: 21 -->
|
||||
|
||||
# `ksp-onchain-transport-lib`
|
||||
|
||||
`ksp-onchain-transport-lib` est la bibliothèque KSP propriétaire du transport on-chain Solana. Elle fournit le transport HTTP JSON-RPC complet et le moteur WebSocket Solana standard ; les extensions provider-specific et gRPC sont ajoutées séparément lorsqu’une release les cible.
|
||||
`ksp-onchain-transport-lib` est la bibliothèque KSP propriétaire du transport on-chain Solana. Elle fournit le transport HTTP JSON-RPC complet, le moteur WebSocket Solana standard et la foundation Yellowstone gRPC standard/provider-neutral. Les extensions provider-specific restent ajoutées séparément lorsqu’une release les cible.
|
||||
|
||||
## Responsabilités
|
||||
|
||||
@@ -21,6 +21,8 @@ La crate possède :
|
||||
- l'exécution générique des méthodes standard supportées ;
|
||||
- les wrappers typés HTTP et WebSocket explicitement livrés par KSP ;
|
||||
- les sessions physiques WebSocket, subscriptions logiques, reconnect/resubscribe et backpressure bornés ;
|
||||
- les settings, channels, unary et sessions `Subscribe` Yellowstone gRPC standard ;
|
||||
- le reconnect/replay Yellowstone prudent avec observabilité de gaps/duplicates sans promesse lossless ;
|
||||
- les snapshots runtime sûrs ;
|
||||
- l'observabilité Transport via `ksp-logging-lib`.
|
||||
|
||||
@@ -37,6 +39,7 @@ ksp-config-lib
|
||||
-> ksp-logging-lib
|
||||
-> reqwest / tokio / serde
|
||||
-> tokio-tungstenite / futures-util
|
||||
-> tonic / tonic-prost / yellowstone-grpc-proto
|
||||
```
|
||||
|
||||
La direction inverse est interdite :
|
||||
@@ -217,6 +220,32 @@ Pour Helius, l’actor envoie automatiquement un control frame WebSocket `Ping`
|
||||
|
||||
LaserStream **gRPC** reste un backend distinct, hors de cette façade, de `WsProtocolKind` et de la Config WebSocket `helius_laserstream`.
|
||||
|
||||
|
||||
## Yellowstone gRPC standard
|
||||
|
||||
La foundation `0.2.9` ajoute un troisième backend réseau distinct de HTTP et WebSocket. Le moteur est KSP-owned : `yellowstone-grpc-proto` fournit le wire publié, tandis que Tonic reste encapsulé derrière les types crate-root KSP. Aucun client Tonic brut ni type protobuf upstream n’est réexporté.
|
||||
|
||||
La surface publique principale comprend :
|
||||
|
||||
```text
|
||||
YellowstoneGrpcEndpointUrl / YellowstoneGrpcEndpointSettings
|
||||
YellowstoneGrpcSessionSettings / YellowstoneGrpcReconnectSettings
|
||||
YellowstoneGrpcTransportSettings
|
||||
YellowstoneGrpcChannel
|
||||
SolanaYellowstoneGrpcUnaryClient
|
||||
YellowstoneSubscribeRequest
|
||||
SolanaYellowstoneGrpcSubscribeSession
|
||||
YellowstoneGrpcSubscribeSnapshot
|
||||
```
|
||||
|
||||
Les sept unary standards retenus sont `SubscribeReplayInfo`, `Ping`, `GetLatestBlockhash`, `GetBlockHeight`, `GetSlot`, `IsBlockhashValid` et `GetVersion`. `Subscribe` couvre accounts, slots, transactions, transaction status, blocks, block metadata et entries, avec `commitment`, `accounts_data_slice`, `ping` et `from_slot`. `SubscribeDeshred` reste hors scope de la foundation standard.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Résilience
|
||||
|
||||
L'admission est calculée par couple endpoint/rôle. Le pool applique :
|
||||
@@ -253,7 +282,7 @@ La configuration Logging de référence conserve un fichier dédié Transport à
|
||||
|
||||
Les tests par défaut sont déterministes et n'exigent pas Internet : fixtures JSON et serveur HTTP local couvrent requêtes, réponses, retry, 429, timeout, redaction et routing.
|
||||
|
||||
Trois smokes Devnet opt-in sont séparés par responsabilité :
|
||||
Quatre smokes réseau opt-in sont séparés par responsabilité :
|
||||
|
||||
```text
|
||||
Transport HTTP pur : settings programmatiques -> HttpTransportPool
|
||||
@@ -270,13 +299,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
|
||||
```
|
||||
|
||||
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 trois tests sont `ignored` par défaut. Les deux 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. 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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -290,4 +322,6 @@ Aucun smoke Helius live supplémentaire n’est committé en `0.2.8-pre.010`. Un
|
||||
- [`../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée Transactions ;
|
||||
- [`../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan Blocks/Economics et compliance HTTP finale ;
|
||||
- [`../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée `52/52 + 14/14` et audit `KSP-TRANSPORT-007` global ;
|
||||
- [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard HTTP + WebSocket V2, avec lecture backward V1 HTTP-only.
|
||||
- [`../../docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md`](../../docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md) — plan Yellowstone gRPC standard/provider-neutral et PublicNode ;
|
||||
- [`../../docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md`](../../docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md) — matrice de compliance Yellowstone ;
|
||||
- [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard Transport V3 HTTP + WebSocket + gRPC, avec lecture backward V1/V2.
|
||||
|
||||
@@ -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 :
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// file: crates/ksp-onchain-transport-lib/tests/yellowstone_publicnode_smoke.rs
|
||||
// version: 1
|
||||
|
||||
//! Opt-in live PublicNode Mainnet smoke for the provider-neutral Yellowstone gRPC facade.
|
||||
|
||||
fn publicnode_mainnet_endpoint() -> ksp_core_lib::Result<ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings> {
|
||||
let url = match ksp_onchain_transport_lib::YellowstoneGrpcEndpointUrl::parse("https://solana-yellowstone-grpc.publicnode.com:443") {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let session = ksp_onchain_transport_lib::YellowstoneGrpcSessionSettings::new(
|
||||
std::time::Duration::from_secs(10),
|
||||
std::time::Duration::from_secs(10),
|
||||
std::time::Duration::from_secs(5),
|
||||
ksp_onchain_transport_lib::YellowstoneGrpcReconnectSettings::new(0, std::time::Duration::from_millis(250), std::time::Duration::from_secs(2)),
|
||||
8,
|
||||
8,
|
||||
16 * 1024 * 1024,
|
||||
4 * 1024 * 1024,
|
||||
);
|
||||
return std::result::Result::Ok(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"),
|
||||
url,
|
||||
session,
|
||||
));
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
#[ignore = "opt-in live PublicNode Mainnet Yellowstone gRPC smoke; performs external TLS and unary gRPC requests"]
|
||||
async fn publicnode_mainnet_yellowstone_reaches_standard_version_and_slot_without_credentials() {
|
||||
let endpoint = publicnode_mainnet_endpoint().expect("programmatic PublicNode Yellowstone settings must construct an endpoint");
|
||||
let channel = ksp_onchain_transport_lib::YellowstoneGrpcChannel::connect(&endpoint).await.expect("PublicNode Yellowstone TLS connection must succeed");
|
||||
assert_eq!(channel.endpoint_name(), "publicnode_mainnet_yellowstone");
|
||||
assert_eq!(channel.provider().as_str(), "publicnode");
|
||||
assert_eq!(channel.cluster().as_str(), "mainnet-beta");
|
||||
let client = channel.standard_unary_client();
|
||||
let version = client.get_version().await.expect("PublicNode Yellowstone GetVersion must succeed");
|
||||
assert!(!version.version().is_empty());
|
||||
let slot = client
|
||||
.get_slot(std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed))
|
||||
.await
|
||||
.expect("PublicNode Yellowstone GetSlot must succeed");
|
||||
assert!(slot.slot() > 0);
|
||||
}
|
||||
Reference in New Issue
Block a user