v0.4.8-pre.005

This commit is contained in:
2026-08-05 19:36:17 +02:00
parent 4c13d7ac54
commit 4187643148
18 changed files with 2448 additions and 169 deletions

View File

@@ -0,0 +1,152 @@
<!-- file: docs/audits/V0_4_8_PRE_005_SOLANA_PROGRAM_METADATA_INSTRUCTION_HISTORY_AUDIT.md -->
<!-- version: 1 -->
# Audit `0.4.8-pre.005` — instructions et historique de Solana Program Metadata
## 1. Objet
Cet audit détermine la surface exacte du décodeur dinstructions du programme :
```text
ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S
```
Il vérifie séparément :
- linventaire stable actuel ;
- les écarts entre lIDL Codama, les clients générés et le processeur on-chain ;
- lexistence éventuelle dinstructions supprimées, remplacées ou obsolètes ;
- la politique de couverture à appliquer dans `kb-lib`.
Laudit ne porte ni sur Metaplex Token Metadata, ni sur les metadata incorporées à Token-2022, ni sur la résolution off-chain des URL.
## 2. Sources de vérité
Les sources officielles retenues sont :
- les tags `program@v1.0.0` et `program@v1.0.1` du dépôt `solana-program/program-metadata` ;
- `program/src/instruction.rs` et lentrypoint du programme ;
- les neuf processeurs sous `program/src/processor/` au tag `program@v1.0.1` ;
- lIDL Codama officielle conservée brute sous `idls/` ;
- les clients Codama générés, utilisés pour distinguer le contrat SDK canonique des formes supplémentaires acceptées par le runtime ;
- lhistorique Git antérieur à la première release stable, utilisé uniquement comme provenance.
Le processeur `program@v1.0.1` est la source de vérité pour les formes réellement acceptées par le runtime actuel. LIDL reste la source de vérité du contrat SDK publié.
## 3. Inventaire stable
Les deux releases stables auditées exposent le même inventaire de neuf instructions :
| Tag | Code Khadhroony | Instruction officielle | Statut |
|----:|-----------------|------------------------|--------|
| `0` | `write` | `Write` | stable |
| `1` | `initialize` | `Initialize` | stable |
| `2` | `set_authority` | `SetAuthority` | stable |
| `3` | `set_data` | `SetData` | stable |
| `4` | `set_immutable` | `SetImmutable` | stable |
| `5` | `trim` | `Trim` | stable |
| `6` | `close` | `Close` | stable |
| `7` | `allocate` | `Allocate` | stable |
| `8` | `extend` | `Extend` | stable |
Aucun discriminant stable supplémentaire na été trouvé. Aucun de ces neuf discriminants nest marqué obsolète dans les releases stables auditées.
## 4. Historique antérieur à la première release stable
### 4.1 Tag `5`
Un commit de travail du 10 janvier 2025 a introduit une instruction nommée `WithdrawExcessLamports` au tag `5`. Le 19 février 2025, avant `program@v1.0.0`, ce même tag a été remplacé par `Trim`.
Cette évolution ne crée pas une dixième instruction à couvrir :
- le discriminant reste `5` ;
- le contrat stable publié est `Trim` ;
- aucune release stable auditée nexpose `WithdrawExcessLamports` comme entrée distincte ;
- le comportement de `Trim` comprend désormais le redimensionnement du compte et le retrait de lexcédent de lamports.
Décision : le décodeur publie uniquement `trim` pour le tag `5`. Le nom pré-stable est conservé dans la provenance de lobservation et dans la matrice, sans entrée de couverture historique distincte.
### 4.2 Autres formes de travail
Lhistorique antérieur à `program@v1.0.0` contient plusieurs changements de wire, de comptes optionnels et de builders. Ils appartiennent à une phase explicitement marquée WIP dans le dépôt.
Aucune compatibilité réseau historique nest déclarée pour ces formes tant quune preuve de déploiement et une transaction de cluster ne sont pas identifiées. Le décodeur ne doit pas inventer des entrées historiques uniquement à partir de commits de développement.
## 5. Écarts runtime / IDL à conserver
### 5.1 `Write`
Le runtime exige un offset `u32` puis sélectionne exactement une source :
- octets restants dans linstruction ;
- ou compte `source_buffer` lorsque le reliquat est vide.
Les deux sources simultanées et labsence des deux sources échouent.
### 5.2 `Initialize`
Le header darguments fixe mesure 20 octets. Le reliquat peut être vide uniquement lorsque le compte metadata est déjà un `Buffer` préalloué ; sinon des données inline sont requises.
Le décodeur peut établir lintention wire, mais la validité de cette condition dépend de létat du compte et sera vérifiée par les lectures stateful futures.
### 5.3 `SetAuthority`
Le SDK encode une option canonique `0` ou `1`. Le runtime traite néanmoins tout flag non nul comme une nouvelle autorité et exige alors exactement 32 octets.
Pour le flag `0`, les octets suffixes sont ignorés sur le chemin `Metadata`. La suppression dautorité reste interdite pour un `Buffer` et cette distinction nécessite létat du compte.
### 5.4 `SetData`
LIDL encode `encoding`, `compression`, `format`, `data_source` puis un reliquat optionnel. Le processeur accepte aussi une forme de trois octets contenant uniquement les trois premiers champs ; cette forme modifie le header sans remplacer les données existantes.
Lorsque `data_source` est présent :
- un reliquat non vide fournit les données inline et impose le placeholder pour `buffer` ;
- un reliquat vide impose un véritable compte `buffer` ;
- les deux sources ou aucune source sont rejetées.
### 5.5 Instructions sans arguments SDK
`SetImmutable`, `Trim` et `Close` ne reçoivent pas leur reliquat depuis lentrypoint. Le runtime ignore donc les octets suivant leur tag, même si le client SDK canonique nen produit aucun.
Le décodeur conserve leur longueur et leur préfixe comme suffixe ignoré ; il ne les interprète pas comme de nouveaux arguments.
### 5.6 Comptes supplémentaires
Le runtime accepte des comptes restants pour `Write`, `Initialize`, `SetData`, `Allocate` et `Extend`. Il exige une longueur exacte pour `SetAuthority`, `SetImmutable`, `Trim` et `Close`.
La matrice contractuelle encode explicitement cette différence.
## 6. Décision de décodage
Le décodeur `DcMetadataSolanaProgramMetadataDecoder` :
- reconnaît uniquement le Program ID officiel ;
- déclare exactement neuf entrées de couverture non historiques ;
- borne la taille de linstruction et le nombre de comptes contextualisés ;
- valide les discriminateurs, longueurs, enums, flags, ordre des comptes et contrats de sources ;
- conserve les variantes runtime actuelles qui dépassent le contrat SDK ;
- conserve les suffixes runtime ignorés sans leur attribuer de sémantique ;
- produit une intention non committée pour une transaction échouée ;
- ne télécharge aucune URL et ne lit aucun compte externe implicitement ;
- ne déclare aucune forme pré-stable comme compatible réseau sans preuve de cluster.
## 7. Artefacts liés
- `test-fixtures/contract-matrices/SOLANA_PROGRAM_METADATA_INSTRUCTION_MATRIX.json` ;
- `kb-lib/src/decoder/metadata/solana_program_metadata/instruction.rs` ;
- `kb-lib/tests/external_solana_program_metadata_instruction_api.rs` ;
- `docs/IDL_AUDIT.md` ;
- `docs/IDL_TO_KB_LIB_NOMENCLATURE.md`.
## 8. Statut de validation
| Niveau | Statut |
|-------------------------------------------------|---------------------------------------------|
| audit de lIDL | validé |
| audit des sources `program@v1.0.1` | validé |
| comparaison `program@v1.0.0` / `program@v1.0.1` | validée, inventaire inchangé |
| audit historique pré-stable | documenté, sans revendication réseau |
| tests synthétiques Rust | à exécuter dans le workspace utilisateur |
| replay de transactions réelles | planifié dans les phases pipeline et Devnet |
| validation Devnet | non encore exécutée |