v0.3.15-pre.008-fix.004
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 612
|
# version: 613
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-raw-transaction-ingest-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"]
|
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-raw-transaction-ingest-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.3.15-pre.8.fix.3"
|
version = "0.3.15-pre.8.fix.4"
|
||||||
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"
|
||||||
|
|||||||
@@ -415,11 +415,11 @@
|
|||||||
"profile_id": "publicnode_mainnet",
|
"profile_id": "publicnode_mainnet",
|
||||||
"endpoints": [
|
"endpoints": [
|
||||||
{
|
{
|
||||||
"name": "solana_mainnet_public",
|
"name": "publicnode_solana_mainnet_rpc",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"provider": "solana-public",
|
"provider": "publicnode",
|
||||||
"cluster": "mainnet",
|
"cluster": "mainnet",
|
||||||
"url": "${KSP_PUBLIC_SOLANA_MAINNET_HTTP_URL:-https://api.mainnet.solana.com}",
|
"url": "https://solana-rpc.publicnode.com",
|
||||||
"connect_timeout_ms": 5000,
|
"connect_timeout_ms": 5000,
|
||||||
"request_timeout_ms": 15000,
|
"request_timeout_ms": 15000,
|
||||||
"max_idle_connections_per_host": 8,
|
"max_idle_connections_per_host": 8,
|
||||||
@@ -432,8 +432,6 @@
|
|||||||
],
|
],
|
||||||
"priority": 100,
|
"priority": 100,
|
||||||
"limits": {
|
"limits": {
|
||||||
"requests_per_second": 5,
|
|
||||||
"burst_capacity": 10,
|
|
||||||
"max_concurrent_requests": 8,
|
"max_concurrent_requests": 8,
|
||||||
"pause_after_rate_limit_ms": 1000
|
"pause_after_rate_limit_ms": 1000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: crates/ksp-app-raw-transaction-ingest-desk/README.md -->
|
<!-- file: crates/ksp-app-raw-transaction-ingest-desk/README.md -->
|
||||||
<!-- version: 8 -->
|
<!-- version: 9 -->
|
||||||
|
|
||||||
# `ksp-app-raw-transaction-ingest-desk`
|
# `ksp-app-raw-transaction-ingest-desk`
|
||||||
|
|
||||||
@@ -50,6 +50,8 @@ Les profils standard publics committés déclarent `Block` en plus de `Logs`; `s
|
|||||||
|
|
||||||
Une route `Configured` est uniquement **composable depuis Config**. La disponibilité réelle du Store et du Worker est revalidée lors du Start avant publication de l'accusé runtime. Les états spontanés après Start ne sont pas encore streamés vers le frontend ; l'observabilité continue est ajoutée par la tranche monitoring dédiée.
|
Une route `Configured` est uniquement **composable depuis Config**. La disponibilité réelle du Store et du Worker est revalidée lors du Start avant publication de l'accusé runtime. Les états spontanés après Start ne sont pas encore streamés vers le frontend ; l'observabilité continue est ajoutée par la tranche monitoring dédiée.
|
||||||
|
|
||||||
|
Pour `yellowstone-hydrated`, le Start utilise désormais le HTTP du **même profil Transport Yellowstone** que le gRPC. Sur Mainnet, le profil `publicnode_mainnet` hydrate donc via `https://solana-rpc.publicnode.com` au lieu de retomber sur `api.mainnet.solana.com`. Le profil PublicNode ne réutilise plus la limite locale Solana-public de `5 req/s`; il conserve une concurrence locale bornée et laisse les réponses `429` piloter le cooldown Transport. Cette correction ne supprime pas encore le coût structurel d'une hydration `getTransaction` par transaction : la réduction de cette dépendance, le pool HTTP multi-provider et le multi-route appartiennent à `pre.009`.
|
||||||
|
|
||||||
## Ports de développement
|
## Ports de développement
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: crates/ksp-app-raw-transaction-ingest-desk/USAGE.md -->
|
<!-- file: crates/ksp-app-raw-transaction-ingest-desk/USAGE.md -->
|
||||||
<!-- version: 7 -->
|
<!-- version: 8 -->
|
||||||
|
|
||||||
# Utilisation de `ksp-app-raw-transaction-ingest-desk`
|
# Utilisation de `ksp-app-raw-transaction-ingest-desk`
|
||||||
|
|
||||||
@@ -44,6 +44,8 @@ Un seul Worker peut être actif ou en démarrage dans cette tranche. Un second S
|
|||||||
|
|
||||||
Le frontend n'effectue aucun polling runtime continu dans cette tranche. Une terminaison spontanée est nettoyée côté backend ; sa projection temps réel vers l'UI appartient au monitoring ultérieur.
|
Le frontend n'effectue aucun polling runtime continu dans cette tranche. Une terminaison spontanée est nettoyée côté backend ; sa projection temps réel vers l'UI appartient au monitoring ultérieur.
|
||||||
|
|
||||||
|
Sur Mainnet, `yellowstone-hydrated` compose le gRPC et l'HTTP depuis la source `transport.yellowstone` déclarée par le composite. Avec le profil committé `publicnode_mainnet`, les notifications Yellowstone PublicNode sont donc hydratées par le RPC HTTP PublicNode du même profil. Ce mode reste une route hydratée : il peut encore être limité par le débit `getTransaction`. La combinaison de plusieurs endpoints HTTP/providers et le chemin Yellowstone direct sans hydration systématique sont volontairement reportés à `pre.009`.
|
||||||
|
|
||||||
## 3. Raisons d'indisponibilité
|
## 3. Raisons d'indisponibilité
|
||||||
|
|
||||||
Les reasons exposées sont des codes applicatifs bornés, par exemple :
|
Les reasons exposées sont des codes applicatifs bornés, par exemple :
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/route_start.rs
|
// file: crates/ksp-app-raw-transaction-ingest-desk/src/route_start.rs
|
||||||
// version: 2
|
// version: 3
|
||||||
|
|
||||||
//! Start-time Config revalidation and exact Transport/Store resource reconstruction for route validation and runtime launch.
|
//! Start-time Config revalidation and exact Transport/Store resource reconstruction for route validation and runtime launch.
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ pub(crate) fn prepare_route_start(
|
|||||||
}
|
}
|
||||||
let commitment = request.commitment.into_transport();
|
let commitment = request.commitment.into_transport();
|
||||||
let runtime_resources = match request.route_id {
|
let runtime_resources = match request.route_id {
|
||||||
crate::RawIngestRouteId::YellowstoneHydrated => prepare_yellowstone(management, &environment, &composite, &transport, network, commitment),
|
crate::RawIngestRouteId::YellowstoneHydrated => prepare_yellowstone(management, &environment, &composite, network, commitment),
|
||||||
crate::RawIngestRouteId::StandardLogsHydrated => prepare_standard_logs(&transport, network, commitment),
|
crate::RawIngestRouteId::StandardLogsHydrated => prepare_standard_logs(&transport, network, commitment),
|
||||||
crate::RawIngestRouteId::StandardBlockDirect => prepare_standard_block(&transport, network, commitment),
|
crate::RawIngestRouteId::StandardBlockDirect => prepare_standard_block(&transport, network, commitment),
|
||||||
crate::RawIngestRouteId::HeliusTransactionHydrated => prepare_helius(management, &environment, &composite, &transport, network, commitment),
|
crate::RawIngestRouteId::HeliusTransactionHydrated => prepare_helius(management, &environment, &composite, &transport, network, commitment),
|
||||||
@@ -260,7 +260,6 @@ fn prepare_yellowstone(
|
|||||||
management: &ksp_config_lib::ConfigManagement,
|
management: &ksp_config_lib::ConfigManagement,
|
||||||
environment: &ksp_config_lib::ConfigEnvironment,
|
environment: &ksp_config_lib::ConfigEnvironment,
|
||||||
composite: &ksp_config_lib::ResolvedConfigComposite,
|
composite: &ksp_config_lib::ResolvedConfigComposite,
|
||||||
base_transport: &ksp_config_lib::ResolvedTransportConfig,
|
|
||||||
network: &str,
|
network: &str,
|
||||||
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
||||||
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources> {
|
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestRuntimeResources> {
|
||||||
@@ -290,12 +289,12 @@ fn prepare_yellowstone(
|
|||||||
return std::result::Result::Err(error);
|
return std::result::Result::Err(error);
|
||||||
}
|
}
|
||||||
request.set_commitment(std::option::Option::Some(commitment));
|
request.set_commitment(std::option::Option::Some(commitment));
|
||||||
let role = single_http_role(base_transport.http_settings(), network, &["getTransaction"]);
|
let role = single_http_role(transport.http_settings(), network, &["getTransaction"]);
|
||||||
let role = match role {
|
let role = match role {
|
||||||
std::result::Result::Ok(value) => value,
|
std::result::Result::Ok(value) => value,
|
||||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
};
|
};
|
||||||
let pool = ksp_onchain_transport_lib::HttpTransportPool::new(base_transport.http_settings().clone());
|
let pool = ksp_onchain_transport_lib::HttpTransportPool::new(transport.http_settings().clone());
|
||||||
let pool = match pool {
|
let pool = match pool {
|
||||||
std::result::Result::Ok(value) => value,
|
std::result::Result::Ok(value) => value,
|
||||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-raw-transaction-ingest-desk/tests/release_completeness.rs
|
// file: crates/ksp-app-raw-transaction-ingest-desk/tests/release_completeness.rs
|
||||||
// version: 6
|
// version: 7
|
||||||
|
|
||||||
//! Release-completeness canaries for Raw Transaction Ingest Desk Start-resource reconstruction.
|
//! Release-completeness canaries for Raw Transaction Ingest Desk Start-resource reconstruction.
|
||||||
|
|
||||||
@@ -106,3 +106,21 @@ fn pre_008_mono_route_slot_blocks_second_start_until_terminal_store_cleanup() {
|
|||||||
assert!(runtime.contains(required), "missing mono-route ownership marker {required}");
|
assert!(runtime.contains(required), "missing mono-route ownership marker {required}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_008_fix_004_yellowstone_hydration_uses_its_declared_transport_source_not_base_transport() {
|
||||||
|
let route_start = read_text(app_root().join("src/route_start.rs").as_path());
|
||||||
|
let start = route_start.find("fn prepare_yellowstone(");
|
||||||
|
let end = route_start.find("fn prepare_http_polling(");
|
||||||
|
assert!(start.is_some());
|
||||||
|
assert!(end.is_some());
|
||||||
|
let yellowstone = match (start, end) {
|
||||||
|
(std::option::Option::Some(start), std::option::Option::Some(end)) if start < end => &route_start[start..end],
|
||||||
|
_ => "",
|
||||||
|
};
|
||||||
|
assert!(yellowstone.contains("resolve_optional_transport"));
|
||||||
|
assert!(yellowstone.contains("COMPOSITE_COMPONENT_ID_TRANSPORT_YELLOWSTONE"));
|
||||||
|
assert!(yellowstone.contains("single_http_role(transport.http_settings(), network, &[\"getTransaction\"])"));
|
||||||
|
assert!(yellowstone.contains("HttpTransportPool::new(transport.http_settings().clone())"));
|
||||||
|
assert!(!yellowstone.contains("base_transport"));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: crates/ksp-config-lib/USAGE.md -->
|
<!-- file: crates/ksp-config-lib/USAGE.md -->
|
||||||
<!-- version: 18 -->
|
<!-- version: 19 -->
|
||||||
|
|
||||||
# Utilisation de ksp-config-lib
|
# Utilisation de ksp-config-lib
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ secret_metadata = metadata dont la valeur doit avoir une provenance KSP_SECRET_*
|
|||||||
|
|
||||||
`protocol` n'est pas un nouveau `WsProtocolKind` et ne transforme pas PublicNode en protocole. Config résout les placeholders, vérifie la classe de sensibilité des metadata puis construit `YellowstoneGrpcTransportSettings`. Transport ne lit jamais l'environnement. Les valeurs de `secret_metadata` sont disponibles au runtime mais redacted dans `safe_value` et dans les représentations `Debug`.
|
`protocol` n'est pas un nouveau `WsProtocolKind` et ne transforme pas PublicNode en protocole. Config résout les placeholders, vérifie la classe de sensibilité des metadata puis construit `YellowstoneGrpcTransportSettings`. Transport ne lit jamais l'environnement. Les valeurs de `secret_metadata` sont disponibles au runtime mais redacted dans `safe_value` et dans les représentations `Debug`.
|
||||||
|
|
||||||
Les profils versionnés `publicnode_mainnet` et `publicnode_testnet` représentent leurs endpoints Yellowstone sous la forme URL TLS requise par Transport et conservent le `x-token` dans `secret_metadata`. Ils restent des sources Transport network-scoped et ne définissent jamais l’identité du réseau applicatif.
|
Les profils versionnés `publicnode_mainnet` et `publicnode_testnet` représentent leurs endpoints Yellowstone sous la forme URL TLS requise par Transport et conservent le `x-token` dans `secret_metadata`. Ils restent des sources Transport network-scoped et ne définissent jamais l’identité du réseau applicatif. `publicnode_mainnet` expose en plus le RPC HTTP Mainnet PublicNode utilisé par les consumers qui doivent hydrater une source Yellowstone same-provider ; ce rôle HTTP ne recopie pas une limite numérique Solana-public qui ne fait pas partie du contrat PublicNode committé.
|
||||||
|
|
||||||
L'accesseur historique `into_transport_settings()` conserve volontairement son tuple `(HTTP, Option<WS>)`. Un consumer ayant besoin des trois backends utilise `into_all_transport_settings()` ou les accesseurs séparés afin de ne pas casser silencieusement les consumers V2.
|
L'accesseur historique `into_transport_settings()` conserve volontairement son tuple `(HTTP, Option<WS>)`. Un consumer ayant besoin des trois backends utilise `into_all_transport_settings()` ou les accesseurs séparés afin de ne pas casser silencieusement les consumers V2.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-config-lib/unit_tests/transport.rs
|
// file: crates/ksp-config-lib/unit_tests/transport.rs
|
||||||
// version: 16
|
// version: 17
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fixture_transport_profile_maps_complete_runtime_contract() {
|
fn fixture_transport_profile_maps_complete_runtime_contract() {
|
||||||
@@ -273,6 +273,19 @@ fn committed_v3_publicnode_profiles_map_provider_neutral_yellowstone_grpc_with_n
|
|||||||
std::result::Result::Err(_) => continue,
|
std::result::Result::Err(_) => continue,
|
||||||
};
|
};
|
||||||
assert_eq!(resolved.profile_id(), profile_id);
|
assert_eq!(resolved.profile_id(), profile_id);
|
||||||
|
if profile_id == "publicnode_mainnet" {
|
||||||
|
assert_eq!(resolved.settings().endpoints().len(), 1);
|
||||||
|
let http = &resolved.settings().endpoints()[0];
|
||||||
|
assert_eq!(http.name(), "publicnode_solana_mainnet_rpc");
|
||||||
|
assert_eq!(http.provider().as_str(), "publicnode");
|
||||||
|
assert_eq!(http.cluster().as_str(), "mainnet");
|
||||||
|
assert_eq!(http.url().as_str(), "https://solana-rpc.publicnode.com");
|
||||||
|
assert_eq!(http.roles().len(), 1);
|
||||||
|
let limits = http.roles()[0].limits();
|
||||||
|
assert!(limits.requests_per_second().is_none());
|
||||||
|
assert!(limits.burst_capacity().is_none());
|
||||||
|
assert_eq!(limits.max_concurrent_requests().map(std::num::NonZeroU32::get), std::option::Option::Some(8));
|
||||||
|
}
|
||||||
assert!(resolved.ws_settings().is_some());
|
assert!(resolved.ws_settings().is_some());
|
||||||
let grpc = resolved.grpc_settings();
|
let grpc = resolved.grpc_settings();
|
||||||
assert!(grpc.is_some(), "PublicNode profile {profile_id} should expose Yellowstone gRPC settings");
|
assert!(grpc.is_some(), "PublicNode profile {profile_id} should expose Yellowstone gRPC settings");
|
||||||
|
|||||||
37
deltas/0.3.15/pre.008-fix.004.md
Normal file
37
deltas/0.3.15/pre.008-fix.004.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<!-- file: deltas/0.3.15/pre.008-fix.004.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta `0.3.15-pre.008-fix.004`
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Corriger la composition Mainnet de `yellowstone-hydrated` observée pendant le gate live de `pre.008-fix.003`, sans avancer le multi-route ni l'optimisation de throughput réservés à `pre.009`.
|
||||||
|
|
||||||
|
## Défaut observé
|
||||||
|
|
||||||
|
Le channel Yellowstone utilisait correctement `publicnode_solana_mainnet_yellowstone`, mais `prepare_yellowstone` construisait le role et le `HttpTransportPool` d'hydration depuis le Transport de base applicatif. Sur Mainnet, cela redirigeait chaque `getTransaction` vers `api.mainnet.solana.com` avec la limite locale `5 req/s`/burst `10`, provoquant cooldown puis overflow alors que le gRPC PublicNode continuait à produire.
|
||||||
|
|
||||||
|
Le profil `publicnode_mainnet` embarquait en outre un endpoint HTTP `solana-public`; le composant Yellowstone n'était donc pas cohérent comme source d'hydration.
|
||||||
|
|
||||||
|
## Correction
|
||||||
|
|
||||||
|
- `prepare_yellowstone` reconstruit désormais gRPC, role HTTP et pool HTTP depuis le même composant `transport.yellowstone` ;
|
||||||
|
- `publicnode_mainnet` utilise `https://solana-rpc.publicnode.com` avec provider `publicnode` pour son endpoint HTTP ;
|
||||||
|
- la limite locale Solana-public `5 req/s`/burst `10` n'est pas copiée vers PublicNode, faute de contrat numérique stable committé ;
|
||||||
|
- la concurrence locale reste bornée à `8` et un `429` continue d'activer le cooldown Transport ;
|
||||||
|
- Helius et les routes standard restent inchangés.
|
||||||
|
|
||||||
|
## Non-claim / suite `pre.009`
|
||||||
|
|
||||||
|
Ce fix ne prétend pas qu'une hydration `getTransaction` par transaction peut soutenir tout Mainnet. `pre.009` doit traiter l'optimisation structurelle : chemin Yellowstone direct lorsque le matériau RAW est disponible, pool HTTP multi-provider, repair par bloc, multi-route, Store partagé same-network et déduplication/idempotence par `(network, signature)`.
|
||||||
|
|
||||||
|
## Version
|
||||||
|
|
||||||
|
```text
|
||||||
|
header racine : 612 -> 613
|
||||||
|
workspace : 0.3.15-pre.8.fix.3 -> 0.3.15-pre.8.fix.4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Rejouer le gate complet de `pre.008` puis vérifier live Mainnet que les traces de `yellowstone-hydrated` montrent l'endpoint HTTP PublicNode et non `solana_mainnet_public`.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md -->
|
<!-- file: docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md -->
|
||||||
<!-- version: 11 -->
|
<!-- version: 12 -->
|
||||||
|
|
||||||
# Plan v0.3.15 — Raw Transaction Ingest Desk
|
# Plan v0.3.15 — Raw Transaction Ingest Desk
|
||||||
|
|
||||||
@@ -791,13 +791,21 @@ Stop
|
|||||||
|
|
||||||
Le slot reste occupé pendant le drain terminal et la fermeture Store ; aucun second Start n'est admis durant cette fenêtre. Le frontend ne reçoit ni `WorkerId`, ni handle, ni endpoint, ni URI Store. La terminaison spontanée est nettoyée backend-side mais son streaming vers le frontend reste `pre.010`. Le partage d'un même Store entre plusieurs Workers reste `pre.009`.
|
Le slot reste occupé pendant le drain terminal et la fermeture Store ; aucun second Start n'est admis durant cette fenêtre. Le frontend ne reçoit ni `WorkerId`, ni handle, ni endpoint, ni URI Store. La terminaison spontanée est nettoyée backend-side mais son streaming vers le frontend reste `pre.010`. Le partage d'un même Store entre plusieurs Workers reste `pre.009`.
|
||||||
|
|
||||||
|
#### `pre.008-fix.004` — cohérence de source Yellowstone Mainnet
|
||||||
|
|
||||||
|
Le test live Mainnet a montré que `yellowstone-hydrated` ouvrait bien le gRPC PublicNode mais reconstruisait son pool `getTransaction` à partir du Transport de base `mainnet_public`, donc `api.mainnet.solana.com`. Le fix impose que le gRPC Yellowstone et son hydration HTTP proviennent du même composant `transport.yellowstone`. Le profil `publicnode_mainnet` utilise désormais `https://solana-rpc.publicnode.com` pour son endpoint HTTP et n'hérite plus de la limite locale Solana-public `5 req/s`; la concurrence reste bornée et les `429` continuent à déclencher le cooldown Transport.
|
||||||
|
|
||||||
|
Ce fix ne prétend pas rendre viable le firehose Mainnet complet par hydration unitaire. La suppression de l'hydration systématique quand Yellowstone porte déjà le matériau transactionnel, le pool HTTP multi-provider, le multi-route, la déduplication cross-route et le repair HTTP par bloc sont explicitement déplacés vers `pre.009`.
|
||||||
|
|
||||||
Budget cible : une tranche runtime mono-route.
|
Budget cible : une tranche runtime mono-route.
|
||||||
|
|
||||||
### `pre.009` — multi-route et Store partagé
|
### `pre.009` — optimisation Mainnet, multi-route et Store partagé
|
||||||
|
|
||||||
Permettre plusieurs routes simultanées avec un Worker indépendant par route, un même Store partagé lorsque le réseau est strictement identique et une isolation des faults entre routes.
|
Permettre plusieurs routes simultanées avec un Worker indépendant par route, un même Store partagé lorsque le réseau est strictement identique et une isolation des faults entre routes. La tranche doit également traiter le goulet observé sur Mainnet : privilégier un chemin Yellowstone direct lorsque le matériau RAW peut être reconstruit sans `getTransaction`, réserver HTTP à la réparation/hydration réellement nécessaire, et introduire un pool HTTP multi-provider dont les quotas, health, cooldown et capabilities restent endpoint-owned.
|
||||||
|
|
||||||
Budget cible : une tranche runtime multi-route.
|
Le Store conserve l'idempotence `(network, signature)` et les observations/provenances permettent à plusieurs routes de confirmer la même transaction sans créer une seconde entité RAW. Le repair HTTP doit privilégier le niveau bloc lorsqu'il permet de récupérer plusieurs transactions par requête.
|
||||||
|
|
||||||
|
Budget cible : une tranche runtime/throughput Mainnet + multi-route.
|
||||||
|
|
||||||
### `pre.010` — snapshots et monitoring runtime
|
### `pre.010` — snapshots et monitoring runtime
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
|
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
|
||||||
<!-- version: 12 -->
|
<!-- version: 13 -->
|
||||||
|
|
||||||
# Validation v0.3.15 — Raw Transaction Ingest Desk
|
# Validation v0.3.15 — Raw Transaction Ingest Desk
|
||||||
|
|
||||||
@@ -413,9 +413,17 @@ Surface IPC sûre ajoutée : `start_route` et `stop_route`, avec `RawIngestRoute
|
|||||||
|
|
||||||
Le frontend fournit un contrôle minimal Start/Stop mono-route et le choix `confirmed`/`finalized`. Il ne prétend pas encore fournir le monitoring continu : une terminaison spontanée est nettoyée backend-side mais sa projection temps réel demeure `pre.010`. Multi-route, Store partagé entre Workers et isolation inter-route demeurent `pre.009`.
|
Le frontend fournit un contrôle minimal Start/Stop mono-route et le choix `confirmed`/`finalized`. Il ne prétend pas encore fournir le monitoring continu : une terminaison spontanée est nettoyée backend-side mais sa projection temps réel demeure `pre.010`. Multi-route, Store partagé entre Workers et isolation inter-route demeurent `pre.009`.
|
||||||
|
|
||||||
### `pre.009` — runtime multi-route
|
#### `pre.008-fix.004` — preuve live Mainnet et correction PublicNode
|
||||||
|
|
||||||
Un Worker par route, même Store si réseau identique, isolation des faults.
|
Le parcours live `pre.008-fix.003` prouve que le channel Yellowstone PublicNode Mainnet s'ouvre et produit des transactions, mais que l'hydration était construite depuis le Transport de base `mainnet_public`. Les traces montraient donc le gRPC `publicnode_solana_mainnet_yellowstone` suivi de requêtes `getTransaction` via `solana_mainnet_public`, puis rate-limit/cooldown et overflow de queue.
|
||||||
|
|
||||||
|
Le fix corrige la composition : `prepare_yellowstone` prend désormais son role/pool HTTP dans le même `ResolvedTransportConfig` optionnel qui fournit le gRPC. Le profil `publicnode_mainnet` expose `publicnode_solana_mainnet_rpc` sur `https://solana-rpc.publicnode.com`, provider `publicnode`, sans recopier la limite locale `5 req/s` du profil Solana-public. La concurrence locale reste bornée à 8 et le cooldown Transport sur `429` reste actif.
|
||||||
|
|
||||||
|
Non-claim : ce changement réduit une erreur de composition mais ne garantit pas qu'une hydration HTTP unitaire puisse suivre le firehose Mainnet. L'optimisation structurelle Yellowstone direct + pool HTTP multi-provider + repair bloc est reportée à `pre.009`.
|
||||||
|
|
||||||
|
### `pre.009` — optimisation Mainnet et runtime multi-route
|
||||||
|
|
||||||
|
Un Worker par route, même Store si réseau identique, isolation des faults, chemin Yellowstone direct lorsque possible, pool HTTP multi-provider et repair par bloc pour éviter que `getTransaction` unitaire soit le chemin nominal du temps réel.
|
||||||
|
|
||||||
### `pre.010` — monitoring
|
### `pre.010` — monitoring
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user