v0.4.8-pre.005
This commit is contained in:
@@ -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 d’instructions du programme :
|
||||
|
||||
```text
|
||||
ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S
|
||||
```
|
||||
|
||||
Il vérifie séparément :
|
||||
|
||||
- l’inventaire stable actuel ;
|
||||
- les écarts entre l’IDL Codama, les clients générés et le processeur on-chain ;
|
||||
- l’existence éventuelle d’instructions supprimées, remplacées ou obsolètes ;
|
||||
- la politique de couverture à appliquer dans `kb-lib`.
|
||||
|
||||
L’audit 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 l’entrypoint du programme ;
|
||||
- les neuf processeurs sous `program/src/processor/` au tag `program@v1.0.1` ;
|
||||
- l’IDL 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 ;
|
||||
- l’historique 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. L’IDL 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 n’a été trouvé. Aucun de ces neuf discriminants n’est 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 n’expose `WithdrawExcessLamports` comme entrée distincte ;
|
||||
- le comportement de `Trim` comprend désormais le redimensionnement du compte et le retrait de l’excé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 l’observation et dans la matrice, sans entrée de couverture historique distincte.
|
||||
|
||||
### 4.2 Autres formes de travail
|
||||
|
||||
L’historique 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 n’est déclarée pour ces formes tant qu’une 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 l’instruction ;
|
||||
- ou compte `source_buffer` lorsque le reliquat est vide.
|
||||
|
||||
Les deux sources simultanées et l’absence des deux sources échouent.
|
||||
|
||||
### 5.2 `Initialize`
|
||||
|
||||
Le header d’arguments 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 l’intention 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 d’autorité reste interdite pour un `Buffer` et cette distinction nécessite l’état du compte.
|
||||
|
||||
### 5.4 `SetData`
|
||||
|
||||
L’IDL 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 l’entrypoint. Le runtime ignore donc les octets suivant leur tag, même si le client SDK canonique n’en 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 l’instruction 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 l’IDL | 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 |
|
||||
Reference in New Issue
Block a user