v0.2.11-pre.008

This commit is contained in:
2026-08-26 10:23:42 +02:00
parent 5aeff5ca14
commit 87d7314bf4
13 changed files with 972 additions and 63 deletions

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md -->
<!-- version: 13 -->
<!-- version: 14 -->
# Plan `0.2.11` — Off-chain price transport SOL/USD multi-provider
**Statut courant : `0.2.11-pre.007` complète les huit adapters `market_price` avec Birdeye Standard et matérialise le registry provider-neutral. Birdeye exige `X-API-KEY`, utilise `/defi/price` sur Solana/WSOL, modélise 1 RPS par compte, 30 000 compute units de quota informatif et 3 compute units par requête SOL/USD. Le registry expose uniquement descriptor + état générique en ordre déterministe ; le dispatch/refresh reste réservé à `pre.008`. Le gate opérateur ciblé de `pre.006` est PASS ; `cargo test --workspace` n'a pas été rejoué sur l'état exact `pre.006`.**
**Statut courant : `0.2.11-pre.008` matérialise le service générique de refresh SOL/USD au-dessus des huit adapters V1. `MarketPriceService` possède le dispatch provider, le registry runtime et les transitions d'availability ; les consumers utilisent uniquement les provider ids opaques, `registry()`, `refresh`, `refresh_many` et `refresh_all`. Les limites/cooldowns restent non bloquants et aucun fallback, consensus ou scheduler provider n'est introduit. `MarketPriceProviderSetup` reste la frontière provider-specific destinée à la composition/Config de `pre.009`. Le gate opérateur complet de `pre.007` est PASS, y compris `cargo test --workspace`.**
## 1. Base et autorité
@@ -436,7 +436,7 @@ misconfigured
disabled
```
`MarketPriceProviderAvailability` et `MarketPriceProviderState` matérialisent cette projection générique dès `pre.002`. `pre.007` ajoute `MarketPriceProviderRegistry` et `MarketPriceProviderRegistryEntry` : le registry est borné, trié de façon déterministe par `provider_id`, rejette les doublons et n'expose que `descriptor + state`. Son module ne contient aucun dispatch par nom de provider. Le registry reste une projection générique sans méthode de dispatch ni transition réseau ; le futur service `pre.008` possédera les mutations runtime et republiera les états mis à jour.
`MarketPriceProviderAvailability` et `MarketPriceProviderState` matérialisent cette projection générique dès `pre.002`. `pre.007` ajoute `MarketPriceProviderRegistry` et `MarketPriceProviderRegistryEntry` : le registry est borné, trié de façon déterministe par `provider_id`, rejette les doublons et n'expose que `descriptor + state`. Son module ne contient aucun dispatch par nom de provider. `pre.008` ajoute `MarketPriceService`, propriétaire du dispatch réel et des mutations d'availability, tout en conservant le registry comme projection générique détachable. `MarketPriceProviderSetup` contient uniquement la sélection provider-specific nécessaire à la composition initiale ; elle ne traverse pas les opérations runtime destinées à la HID.
`MarketPriceProviderAvailability` expose aussi génériquement l'éligibilité immédiate au refresh et un `retry_at` lorsqu'il est réellement connu. `AuthenticationUnavailable`, `QuotaUnavailable`, `Misconfigured`, `Disabled`, `CoolingDown`, `TemporarilyUnavailable` et `Ready` restent distincts sans parsing provider dans les consumers.
@@ -516,7 +516,7 @@ Il n'existe pas d'URL provider arbitraire dans la Config V1. Cela évite SSRF, r
Les primitives `http_*` sont **crate-private** : elles ne créent pas un client HTTP générique public contournant les capacités métier. Les adapters `market_price_*`, puis de futures familles telles que `swap_quote_*`, les consomment derrière leur propre contrat.
Le limiter `pre.003` est non bloquant. Une cadence fixe est matérialisée par un token bucket lissé ; lorsqu'aucun burst n'est documenté, la capacité locale initiale reste volontairement `1`. Lorsqu'un burst est documenté, sa capacité est indépendante du nombre moyen de requêtes de la fenêtre et peut donc lui être supérieure. Une limite dynamique n'invente aucune cadence locale et apprend seulement des réponses provider, notamment `429`. Un `Retry-After` serveur peut prolonger le cooldown mais ne peut pas dépasser une borne défensive d'une heure. Aucune primitive HTTP commune ne dort en attendant la disponibilité : elle expose un délai de defer que l'orchestrateur `pre.008` pourra projeter provider par provider.
Le limiter `pre.003` est non bloquant. Une cadence fixe est matérialisée par un token bucket lissé ; lorsqu'aucun burst n'est documenté, la capacité locale initiale reste volontairement `1`. Lorsqu'un burst est documenté, sa capacité est indépendante du nombre moyen de requêtes de la fenêtre et peut donc lui être supérieure. Une limite dynamique n'invente aucune cadence locale et apprend seulement des réponses provider, notamment `429`. Un `Retry-After` serveur peut prolonger le cooldown mais ne peut pas dépasser une borne défensive d'une heure. `pre.008` projette ces délais dans `MarketPriceProviderAvailability` et ne dort jamais : `refresh`, `refresh_many` et `refresh_all` retournent immédiatement un état non éligible lorsqu'un prochain instant admissible est encore dans le futur.
## 15. Config provider-capability-aware
@@ -740,15 +740,15 @@ Implémentation des adapters Jupiter Price V3 et DexScreener avec DTOs wire priv
### `pre.007` — Birdeye, registry et availability
**Statut : réalisé, gate Cargo opérateur à exécuter.**
**Statut : réalisé, gate opérateur complet PASS.**
Implémentation de Birdeye Standard avec `X-API-KEY`, endpoint Price Single Solana/WSOL, prix exact et timestamp provider réel. Le descriptor modélise 1 RPS par compte, 30 000 compute units de quota informatif et 3 compute units par refresh SOL/USD. `MarketPriceProviderRegistry` finalise l'inventaire runtime provider-neutral des huit adapters sous forme d'entrées `descriptor + state`, avec ordre déterministe et doublons rejetés. Les transitions runtime et le dispatch restent réservés à `pre.008`. Aucun dispatch de refresh, Config ou smoke live n'est avancé.
### `pre.008` — Refresh individuel et multiple
**Statut : planifié.**
**Statut : réalisé, gate Cargo opérateur à exécuter.**
Service de refresh single/multiple, orchestration rate-limit-aware et tests cross-provider sans scheduling provider dans les consumers.
`MarketPriceService` possède les huit adapters configurés, le registry runtime et le dispatch provider-specific interne. La construction accepte `MarketPriceProviderSetup` pour la future couche de composition, puis l'usage devient intégralement provider-agnostic via `registry()`, `refresh(provider_id)`, `refresh_many(...)` et `refresh_all()`. Les échecs provider sont classés en availability générique ; un résultat en erreur n'interrompt pas les autres providers d'un batch. Les états non éligibles sont projetés sans requête réseau, les cooldowns expirés redeviennent tentables, et aucune opération ne dort pour attendre un rate limit. Aucun fallback, consensus, agrégation, Config ou scheduling périodique n'est avancé.
### `pre.009` — Config Off-chain Transport