194 lines
6.6 KiB
Markdown
194 lines
6.6 KiB
Markdown
<!-- file: crates/ksp-interface-lib/README.md -->
|
|
<!-- version: 3 -->
|
|
|
|
# ksp-interface-lib
|
|
|
|
`ksp-interface-lib` possède les contrats passifs KSP qui doivent être partagés entre plusieurs composants sans imposer leur runtime d'origine. Sa surface couvre actuellement deux familles distinctes : les contrats wire Program génériques et un petit ensemble de faits d'acquisition provider-neutral dont la sémantique commune a été démontrée.
|
|
|
|
La crate reste une façade de représentation. Elle ne possède ni transport réseau, ni event bus, ni worker/job, ni persistence, ni exécution, ni comportement métier Program.
|
|
|
|
## Ownership
|
|
|
|
La crate réutilise les primitives fondamentales déjà possédées par `ksp-core-lib` :
|
|
|
|
```text
|
|
Pubkey
|
|
Error / ErrorCode / Result
|
|
Program IDs fondamentaux
|
|
```
|
|
|
|
`Pubkey` est réexporté depuis le crate-root Interface afin qu'un consumer n'introduise aucun wrapper d'identité parallèle. Les Program IDs restent possédés et répertoriés par Core.
|
|
|
|
Le graphe normal reste strictement :
|
|
|
|
```text
|
|
ksp-interface-lib
|
|
└── ksp-core-lib
|
|
└── solana-pubkey
|
|
```
|
|
|
|
La crate ne possède aucune feature Cargo, aucune `dev-dependency` et aucune `build-dependency` runtime propre.
|
|
|
|
## Surface publique
|
|
|
|
La façade crate-root expose :
|
|
|
|
```text
|
|
Pubkey
|
|
ProgramAccountMeta
|
|
MAX_PROGRAM_INSTRUCTION_ACCOUNTS
|
|
ProgramInstruction
|
|
MAX_PROGRAM_INSTRUCTION_DATA_LEN
|
|
ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED
|
|
SlotLifecycleStage
|
|
SlotLifecycleEvent
|
|
TransactionSignature
|
|
TransactionExecutionOutcome
|
|
TransactionExecutionEvent
|
|
```
|
|
|
|
Aucun module interne n'est public.
|
|
|
|
## Contrats Program passifs
|
|
|
|
### `ProgramAccountMeta`
|
|
|
|
`ProgramAccountMeta` représente un compte ordonné d'une instruction avec :
|
|
|
|
```text
|
|
pubkey
|
|
is_signer
|
|
is_writable
|
|
```
|
|
|
|
Les champs restent privés. Les constructeurs publics sont `readonly(pubkey, is_signer)` et `writable(pubkey, is_signer)`, complétés par les accessors `pubkey()`, `is_signer()` et `is_writable()`.
|
|
|
|
La structure n'applique aucune sémantique spécifique à un programme et n'exige pas que la `Pubkey` appartienne au registry des Program IDs Core.
|
|
|
|
### `ProgramInstruction`
|
|
|
|
`ProgramInstruction` représente un contrat passif borné :
|
|
|
|
```text
|
|
program_id
|
|
accounts: Vec<ProgramAccountMeta>
|
|
data: Vec<u8>
|
|
```
|
|
|
|
`ProgramInstruction::try_new` consomme directement les deux `Vec`, conserve l'ordre et les doublons des accounts et préserve les octets opaques de `data` sans décodage.
|
|
|
|
Les cas vides sont valides et une `program_id` inconnue du registry KSP reste admissible.
|
|
|
|
### Bornes d'admission
|
|
|
|
| Limite | Valeur |
|
|
|------------------------------------|----------|
|
|
| `MAX_PROGRAM_INSTRUCTION_ACCOUNTS` | `255` |
|
|
| `MAX_PROGRAM_INSTRUCTION_DATA_LEN` | `10_240` |
|
|
|
|
Ces valeurs sont des **bornes d'admission Interface**. Elles ne constituent pas une garantie qu'une instruction donnée respecte à elle seule toutes les contraintes d'une transaction Solana complète.
|
|
|
|
Un dépassement utilise le code commun :
|
|
|
|
```text
|
|
interface.program_instruction_limit_exceeded
|
|
```
|
|
|
|
Le contexte d'erreur est limité aux métadonnées sûres `field`, `actual_len` et `maximum_len`. Aucun payload arbitraire ni account meta hostile n'est recopié dans l'erreur.
|
|
|
|
Le `Debug` de `ProgramInstruction` est volontairement borné : il affiche `program_id`, `account_count` et `data_len`, jamais les accounts complets ni les octets du payload.
|
|
|
|
## Faits passifs d'acquisition
|
|
|
|
Les événements Interface sont des **projections provider-neutral supplémentaires**. Ils ne remplacent jamais les DTOs riches de `ksp-onchain-transport-lib` et ne deviennent jamais la source de vérité durable d'un backlog.
|
|
|
|
La conversion depuis un DTO HTTP/WS/gRPC/provider appartient à la composition ou au consumer qui connaît les deux contrats. `ksp-interface-lib` ne dépend donc pas de Transport.
|
|
|
|
### `SlotLifecycleEvent`
|
|
|
|
`SlotLifecycleEvent` conserve exactement :
|
|
|
|
```text
|
|
slot: u64
|
|
stage: SlotLifecycleStage
|
|
```
|
|
|
|
Les stages actuellement représentés sont :
|
|
|
|
```text
|
|
Processed
|
|
FirstShredReceived
|
|
Completed
|
|
CreatedBank
|
|
Dead
|
|
OptimisticallyConfirmed
|
|
Rooted
|
|
```
|
|
|
|
`SlotLifecycleStage` est `#[non_exhaustive]` afin qu'un consumer externe traite explicitement l'évolution future de l'enum.
|
|
|
|
Parent, timestamp, diagnostics de slot mort, source/provider, filter/session metadata et autres détails Transport ne sont pas copiés dans ce contrat minimal.
|
|
|
|
### `TransactionExecutionEvent`
|
|
|
|
`TransactionExecutionEvent` conserve exactement :
|
|
|
|
```text
|
|
slot: u64
|
|
signature: TransactionSignature
|
|
outcome: TransactionExecutionOutcome
|
|
```
|
|
|
|
`TransactionSignature` contient exactement les 64 bytes canoniques déjà décodés d'une signature Solana. Son `Debug` ne rend pas les bytes.
|
|
|
|
`TransactionExecutionOutcome` distingue uniquement :
|
|
|
|
```text
|
|
Succeeded
|
|
Failed
|
|
```
|
|
|
|
L'enum est `#[non_exhaustive]`. Le contrat ne contient aucun log, payload RAW, erreur provider, commitment, provenance, network id, source metadata ni détail d'exécution arbitraire. Une source ambiguë ou insuffisante doit rester dans son owner Transport au lieu de forcer un événement Interface.
|
|
|
|
## Codecs et runtime
|
|
|
|
La crate n'ajoute aucun codec ou runtime par réflexe :
|
|
|
|
```text
|
|
serde / serde_json absents
|
|
borsh absent tant qu'aucun wire réel ne le requiert
|
|
wincode absent tant qu'aucun wire réel ne le requiert
|
|
bincode interdit pour les codecs wire KSP
|
|
transport/runtime réseau absent
|
|
logging runtime absent
|
|
```
|
|
|
|
Des codecs/layouts/discriminants spécifiques peuvent être ajoutés uniquement lorsqu'un protocole réel en démontre le besoin et que leur ownership wire appartient bien à Interface.
|
|
|
|
Les événements passifs ne constituent pas un comportement runtime. La crate ne dépend donc pas de `ksp-logging-lib` et ne possède ni `constants.rs` ni `TRACING_TARGET`.
|
|
|
|
## Frontières
|
|
|
|
`ksp-interface-lib` ne possède pas :
|
|
|
|
```text
|
|
RPC / WebSocket / gRPC
|
|
provider DTOs Transport
|
|
sessions / reconnect / backpressure
|
|
Config / environnement
|
|
persistence / Store / cursor / retention
|
|
notifications post-commit Store
|
|
worker / job / scheduler / event bus
|
|
Program decoding / recognition / proofs
|
|
execution policy / signers
|
|
RawTransaction / RawAccountState
|
|
```
|
|
|
|
Les données persistantes/replayables restent dans `ksp-store-api`. Les notifications post-commit de données persistées restent un contrat Store API lorsqu'un publisher/consumer réel les justifie. Les faits réseau riches restent Transport-owned.
|
|
|
|
## Références
|
|
|
|
- [Usage public](USAGE.md)
|
|
- [Architecture Wire + Program](../../docs/architecture/006-WIRE_AND_PROGRAM.md)
|
|
- [Architecture Acquisition/Workers/Jobs](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md)
|