v0.2.11-pre.004
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<!-- file: docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Plan `0.2.11` — Off-chain price transport SOL/USD multi-provider
|
||||
|
||||
**Statut courant : `0.2.11-pre.003-fix.001` corrige la conformité crate-root/ordre Rust de la fondation HTTP, autorise les bursts documentés supérieurs à la cadence moyenne et stage les helpers `http_*` sous `cfg(test)` conformément à `RUST-API-008` jusqu'à leur première consommation de production en `pre.004`. `market_price_*` reste la seule famille métier actuelle et demeure limitée à SOL/USD.**
|
||||
**Statut courant : `0.2.11-pre.004` active les primitives `http_*` en production et implémente les trois premiers adapters `market_price_*` — CoinGecko, CoinMarketCap et CoinPaprika — en SOL/USD uniquement, sans SDK provider. Le staging `cfg(test)` de `pre.003-fix.001` disparaît donc structurellement avec leurs premiers consumers de production. CoinMarketCap utilise la surface Simple Price V2 actuelle ; la surface V1 deprecated n'est pas introduite.**
|
||||
|
||||
## 1. Base et autorité
|
||||
|
||||
@@ -208,6 +208,8 @@ https://www.coingecko.com/en/api/pricing
|
||||
|
||||
https://coinmarketcap.com/api/documentation/pro-api-reference/keyless-public-api
|
||||
https://coinmarketcap.com/api/documentation/pro-api-reference/cryptocurrency
|
||||
https://coinmarketcap.com/api/documentation/pro-api-reference/cryptocurrency/simple-price-v2
|
||||
https://coinmarketcap.com/api/documentation/pro-api-reference/cryptocurrency/simple-price-v1
|
||||
https://coinmarketcap.com/api/pricing
|
||||
|
||||
https://docs.coinpaprika.com/api-reference/rest-api/introduction
|
||||
@@ -237,6 +239,8 @@ https://docs.dexscreener.com/
|
||||
|
||||
Les chiffres externes sont une photographie d'audit, pas une constante éternelle. Les adapters doivent rester capables de classer `429` et les informations serveur sans supposer que la documentation ne changera jamais.
|
||||
|
||||
Réaudit `pre.004` : CoinMarketCap Simple Price est implémenté sur la surface **V2** actuelle. La surface Simple Price V1 est documentée comme deprecated et n'est pas utilisée par KSP. Les deux modes V1 retenus restent distincts : endpoint public keyless V2 sans credential, ou endpoint Pro V2 Basic avec `X-CMC_PRO_API_KEY`.
|
||||
|
||||
### 6.1 Gratuité technique et conditions d'usage
|
||||
|
||||
Le verdict `IN` signifie ici qu'un accès HTTP gratuit permet techniquement de développer et live-tester le provider dans `0.2.11`. Il ne constitue pas une affirmation de gratuité commerciale permanente.
|
||||
@@ -698,15 +702,15 @@ Client HTTP REST commun crate-private, classification d'erreurs HTTP/reqwest, bo
|
||||
|
||||
#### `pre.003-fix.001` — Façade crate-root, staging et burst documenté
|
||||
|
||||
**Statut : réalisé, gate Cargo opérateur à rejouer.**
|
||||
**Statut : réalisé ; gate Cargo/Clippy/tests PASS, `RUST-FMT-108` structurel repris par `pre.004`.**
|
||||
|
||||
Correction de l'ordre alphabétique des constantes d'erreur, utilisation systématique de la façade crate-root pour les items `http_*` partagés (`impl crate::...` et signatures crate-wide), suppression des `#[allow(dead_code)]` préparatoires au profit de `#[cfg(test)]` conformément à `RUST-API-008`, et correction du contrat de burst : un burst documenté peut dépasser la cadence moyenne de la fenêtre, comme le cas Coinbase `10 req/s, burst 15`. La version technique workspace devient `0.2.11-pre.3.fix.1`.
|
||||
|
||||
### `pre.004` — CoinGecko, CoinMarketCap et CoinPaprika
|
||||
|
||||
**Statut : planifié.**
|
||||
**Statut : réalisé, gate Cargo opérateur à exécuter.**
|
||||
|
||||
Implémentation des trois adapters d'agrégateurs avec leurs DTOs wire privés et tests dédiés.
|
||||
Activation en production du socle `http_*` et implémentation des trois adapters d'agrégateurs avec DTOs wire privés, parsing décimal exact via `RawValue`, timestamps provider lorsque fournis, endpoints officiels fixes, auth correspondant aux capacités réelles et limites provider décrites dans leurs descriptors. CoinGecko supporte keyless ou Demo key, CoinMarketCap keyless ou Basic key sur Simple Price V2, CoinPaprika reste keyless. Aucun registry global, Config ou smoke live n'est avancé.
|
||||
|
||||
### `pre.005` — Kraken et Coinbase Exchange
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md -->
|
||||
<!-- version: 7 -->
|
||||
<!-- version: 8 -->
|
||||
|
||||
# Validation `0.2.11` — Off-chain price transport SOL/USD
|
||||
|
||||
@@ -105,24 +105,25 @@ Cette correction reste dans la responsabilité de `pre.002` : elle stabilise la
|
||||
|
||||
## 3.4 Gate `0.2.11-pre.003`
|
||||
|
||||
| Critère | Statut | Preuve |
|
||||
|-----------------------------------------------------------------------|---------|-----------------------------------------------------|
|
||||
| version workspace `0.2.11-pre.3` | PASS | `Cargo.toml` racine |
|
||||
| `reqwest` utilisé directement, sans SDK provider | PASS | manifest `ksp-offchain-transport-lib` |
|
||||
| primitives HTTP communes sous modules `http_*` crate-private | PASS | `http_client`, `http_settings`, `http_admission` |
|
||||
| client HTTP générique non exporté aux consumers | PASS | façade `lib.rs` |
|
||||
| redirects, Referer, proxy système et retries reqwest désactivés | PASS | construction `HttpRestClient` |
|
||||
| connect/request timeouts bornés | PASS | `HttpClientSettings` |
|
||||
| body borné pendant lecture chunked avant désérialisation | PASS | `HttpRestClient::get_json` |
|
||||
| JSON syntaxiquement validé sans normalisation numérique intermédiaire | PASS | `serde::de::IgnoredAny` sur bytes bruts |
|
||||
| 401/403, 429, 408/5xx et autres statuts distingués | PASS | codes d'erreur HTTP dédiés |
|
||||
| URL reqwest supprimée des sources d'erreur | PASS | `reqwest::Error::without_url` |
|
||||
| body remote non recopié dans les erreurs | PASS | erreurs construites uniquement depuis metadata safe |
|
||||
| limiter fixe lissé et burst absent traité conservativement | PASS | `HttpAdmissionController` |
|
||||
| limite dynamique n'invente pas de cadence locale | PASS | `HttpAdmissionPolicy::Dynamic` |
|
||||
| cooldown `Retry-After` borné et admission non bloquante | PASS | `record_rate_limited` + `try_admit` |
|
||||
| adapters CoinGecko/Jupiter/etc. ajoutés | N/A | explicitement réservés à `pre.004+` |
|
||||
| gate Cargo complet sur `pre.003-fix.001` | PENDING | à rejouer par l'opérateur après le correctif |
|
||||
| Critère | Statut | Preuve |
|
||||
|-----------------------------------------------------------------------|--------|-----------------------------------------------------|
|
||||
| version workspace `0.2.11-pre.3` | PASS | `Cargo.toml` racine |
|
||||
| `reqwest` utilisé directement, sans SDK provider | PASS | manifest `ksp-offchain-transport-lib` |
|
||||
| primitives HTTP communes sous modules `http_*` crate-private | PASS | `http_client`, `http_settings`, `http_admission` |
|
||||
| client HTTP générique non exporté aux consumers | PASS | façade `lib.rs` |
|
||||
| redirects, Referer, proxy système et retries reqwest désactivés | PASS | construction `HttpRestClient` |
|
||||
| connect/request timeouts bornés | PASS | `HttpClientSettings` |
|
||||
| body borné pendant lecture chunked avant désérialisation | PASS | `HttpRestClient::get_json` |
|
||||
| JSON syntaxiquement validé sans normalisation numérique intermédiaire | PASS | `serde::de::IgnoredAny` sur bytes bruts |
|
||||
| 401/403, 429, 408/5xx et autres statuts distingués | PASS | codes d'erreur HTTP dédiés |
|
||||
| URL reqwest supprimée des sources d'erreur | PASS | `reqwest::Error::without_url` |
|
||||
| body remote non recopié dans les erreurs | PASS | erreurs construites uniquement depuis metadata safe |
|
||||
| limiter fixe lissé et burst absent traité conservativement | PASS | `HttpAdmissionController` |
|
||||
| limite dynamique n'invente pas de cadence locale | PASS | `HttpAdmissionPolicy::Dynamic` |
|
||||
| cooldown `Retry-After` borné et admission non bloquante | PASS | `record_rate_limited` + `try_admit` |
|
||||
| adapters CoinGecko/Jupiter/etc. ajoutés | N/A | explicitement réservés à `pre.004+` |
|
||||
| gate Cargo `check`/`clippy`/tests Off-chain sur `pre.003-fix.001` | PASS | résultats opérateur du 2026-08-25 |
|
||||
| audit Rust final de `pre.003-fix.001` | CARRY | seul `RUST-FMT-108`, cause supprimée en `pre.004` |
|
||||
|
||||
Les tests déterministes de `pre.003` couvrent en particulier le body chunked dépassant la limite, le refus des redirects, un `429` avec `Retry-After`, la non-propagation d'un body distant canari, le JSON invalide et le refill/cooldown du limiter.
|
||||
|
||||
@@ -141,15 +142,43 @@ contrat limiter : burst documenté indépendant de la cadence moyenne et autoris
|
||||
|
||||
Le cas `1 req/s` avec `burst 2` devient un canari déterministe ; il protège notamment la représentabilité du cas Coinbase documenté dans le plan à `10 req/s, burst 15`. Les modules `http_*` restent donc testés et prêts en `pre.003`, mais leur compilation normale sera activée en `pre.004` lorsque les premiers adapters de production les consommeront réellement.
|
||||
|
||||
La version Cargo du correctif est `0.2.11-pre.3.fix.1`. Les audits statiques du sandbox sont propres ; le gate Cargo complet doit être rejoué par l'opérateur.
|
||||
La version Cargo du correctif est `0.2.11-pre.3.fix.1`. Le gate opérateur du `2026-08-25` confirme `cargo check --workspace` PASS, `cargo clippy --workspace --all-targets` PASS et `cargo test -p ksp-offchain-transport-lib` PASS avec 22 unitaires, 2 boundary et 2 public API. L'audit Rust signale uniquement `RUST-FMT-108` dans `src/lib.rs`, conséquence directe du staging `#[cfg(test)]` des modules `http_*`. L'opérateur a explicitement décidé de ne pas publier un fix artificiel pour ce point puisque `pre.004` retire ce staging avec les premiers consumers de production.
|
||||
|
||||
## 3.6 Gate `0.2.11-pre.004`
|
||||
|
||||
| Critère | Statut | Preuve |
|
||||
|------------------------------------------------------------------------|---------|-----------------------------------------------------------|
|
||||
| version workspace `0.2.11-pre.4` | PASS | `Cargo.toml` racine |
|
||||
| modules `http_*` actifs en production, sans staging crate-root test | PASS | `src/lib.rs` |
|
||||
| cause `RUST-FMT-108` de `pre.003-fix.001` supprimée | PASS | modules production avant tests |
|
||||
| CoinGecko SOL/USD adapter public | PASS | `market_price_coingecko.rs` |
|
||||
| CoinGecko keyless et Demo key distingués | PASS | settings + descriptor + header sensible |
|
||||
| CoinMarketCap SOL/USD adapter public | PASS | `market_price_coinmarketcap.rs` |
|
||||
| CoinMarketCap Simple Price V2 utilisé, V1 deprecated absent du runtime | PASS | endpoints V2 fixes + canari dependency boundary |
|
||||
| CoinMarketCap keyless et Basic key distingués | PASS | settings + descriptor + header sensible |
|
||||
| CoinPaprika SOL/USD adapter public | PASS | `market_price_coinpaprika.rs` |
|
||||
| CoinPaprika sans faux credential | PASS | settings keyless uniquement |
|
||||
| prix JSON provider parsé exactement sans passage par `f64` | PASS | `RawValue` -> `MarketPriceDecimal::parse_json_raw` |
|
||||
| timestamps provider conservés lorsqu'ils existent | PASS | Unix seconds CoinGecko, RFC3339 CoinMarketCap/CoinPaprika |
|
||||
| DTOs wire provider privés | PASS | structs privées dans chaque module provider |
|
||||
| endpoints provider fixes et HTTPS | PASS | constantes privées + `HttpGetRequest::new_https` |
|
||||
| API keys absentes de `Debug` et diagnostics | PASS | `MarketPriceApiKey` redacted + tests settings |
|
||||
| `429` alimente le cooldown local partagé | PASS | `get_json` -> `record_rate_limited` |
|
||||
| aucun SDK provider | PASS | manifest + boundary tests |
|
||||
| Config, registry global et refresh multiple non avancés | PASS | scopes réservés à `pre.007+` / `pre.009` |
|
||||
| audit Rust sandbox | PASS | clean, 0 candidate export |
|
||||
| audit Markdown sandbox | PASS | à recalculer après finalisation documentaire |
|
||||
| gate Cargo complet `pre.004` | PENDING | opérateur |
|
||||
|
||||
Les tests déterministes de `pre.004` couvrent les modes d'auth, les headers sans fuite de credential, les URLs/query fixes, le parsing des réponses SOL/USD, le rejet d'identités ou schémas incohérents et le parsing exact des nombres JSON. Aucun smoke réseau n'est revendiqué dans cette tranche.
|
||||
|
||||
## 4. Matrice provider prévue
|
||||
|
||||
| Provider | SOL/USD V1 | Gratuit V1 | Mode auth prévu | Test déterministe | Smoke live | Statut courant |
|
||||
|-------------------|------------|------------|----------------------|-------------------|------------|----------------|
|
||||
| CoinGecko | Oui | Oui | keyless ou Demo key | PLANNED | PLANNED | AUDITED |
|
||||
| CoinMarketCap | Oui | Oui | keyless ou Basic key | PLANNED | PLANNED | AUDITED |
|
||||
| CoinPaprika | Oui | Oui | aucune | PLANNED | PLANNED | AUDITED |
|
||||
| CoinGecko | Oui | Oui | keyless ou Demo key | PASS | PLANNED | IMPLEMENTED |
|
||||
| CoinMarketCap | Oui | Oui | keyless ou Basic key | PASS | PLANNED | IMPLEMENTED |
|
||||
| CoinPaprika | Oui | Oui | aucune | PASS | PLANNED | IMPLEMENTED |
|
||||
| Kraken | Oui | Oui | aucune | PLANNED | PLANNED | AUDITED |
|
||||
| Coinbase Exchange | Oui | Oui | aucune | PLANNED | PLANNED | AUDITED |
|
||||
| Jupiter Price V3 | Oui | Oui | keyless ou Free key | PLANNED | PLANNED | AUDITED |
|
||||
@@ -185,8 +214,8 @@ Avant la stable, les conditions d'usage et la persistance des offres gratuites d
|
||||
| cadence locale fixe représentable | PASS |
|
||||
| burst documenté supérieur à la cadence moyenne représentable | PASS |
|
||||
| limite dynamique keyless représentable | PASS |
|
||||
| `429` classé | PLANNED |
|
||||
| `Retry-After` honoré lorsqu'exploitable | PLANNED |
|
||||
| `429` classé | PASS |
|
||||
| `Retry-After` honoré lorsqu'exploitable | PASS |
|
||||
| cooldown expose prochain instant admissible | PLANNED |
|
||||
| refresh all ne lance que les providers éligibles | PLANNED |
|
||||
| provider en cooldown ne bloque pas les autres | PLANNED |
|
||||
@@ -197,36 +226,36 @@ Avant la stable, les conditions d'usage et la persistance des offres gratuites d
|
||||
|
||||
## 7. Numeric safety
|
||||
|
||||
| Cas | Statut |
|
||||
|-----------------------------------------------------|---------|
|
||||
| décimal string valide | PASS |
|
||||
| JSON number valide sans passage canonique par `f64` | PLANNED |
|
||||
| notation scientifique bornée | PASS |
|
||||
| coefficient/scale overflow rejeté | PASS |
|
||||
| valeur négative rejetée | PASS |
|
||||
| zéro rejeté pour une observation réussie | PASS |
|
||||
| NaN/Inf impossibles dans le type canonique | PASS |
|
||||
| serialization canonique sans perte | PASS |
|
||||
| round-trip public déterministe | PASS |
|
||||
| Cas | Statut |
|
||||
|-----------------------------------------------------|--------|
|
||||
| décimal string valide | PASS |
|
||||
| JSON number valide sans passage canonique par `f64` | PASS |
|
||||
| notation scientifique bornée | PASS |
|
||||
| coefficient/scale overflow rejeté | PASS |
|
||||
| valeur négative rejetée | PASS |
|
||||
| zéro rejeté pour une observation réussie | PASS |
|
||||
| NaN/Inf impossibles dans le type canonique | PASS |
|
||||
| serialization canonique sans perte | PASS |
|
||||
| round-trip public déterministe | PASS |
|
||||
|
||||
## 8. HTTP et sécurité
|
||||
|
||||
| Invariant | Statut |
|
||||
|------------------------------------------------|---------|
|
||||
| `reqwest` seul client provider | PLANNED |
|
||||
| aucun SDK provider | PLANNED |
|
||||
| endpoint provider officiel fixe en V1 | PLANNED |
|
||||
| redirects désactivés | PLANNED |
|
||||
| proxy implicite désactivé selon policy KSP | PLANNED |
|
||||
| connect timeout borné | PLANNED |
|
||||
| request timeout borné | PLANNED |
|
||||
| body réponse borné avant parsing | PLANNED |
|
||||
| URL retirée des erreurs reqwest | PLANNED |
|
||||
| réponse remote brute absente des KspError/logs | PLANNED |
|
||||
| API key absente de Debug/log/error | PLANNED |
|
||||
| 401/403 classés auth/access | PLANNED |
|
||||
| 429 classé rate limit | PLANNED |
|
||||
| 5xx classé transient | PLANNED |
|
||||
| `reqwest` seul client provider | PASS |
|
||||
| aucun SDK provider | PASS |
|
||||
| endpoint provider officiel fixe en V1 | PASS |
|
||||
| redirects désactivés | PASS |
|
||||
| proxy implicite désactivé selon policy KSP | PASS |
|
||||
| connect timeout borné | PASS |
|
||||
| request timeout borné | PASS |
|
||||
| body réponse borné avant parsing | PASS |
|
||||
| URL retirée des erreurs reqwest | PASS |
|
||||
| réponse remote brute absente des KspError/logs | PASS |
|
||||
| API key absente de Debug/log/error | PASS |
|
||||
| 401/403 classés auth/access | PASS |
|
||||
| 429 classé rate limit | PASS |
|
||||
| 5xx classé transient | PASS |
|
||||
| schema drift classé provider protocol | PLANNED |
|
||||
|
||||
## 9. DexScreener V1
|
||||
|
||||
Reference in New Issue
Block a user