v0.4.8-pre.005
This commit is contained in:
@@ -1,8 +1,20 @@
|
||||
<!-- file: kb-lib/CHANGELOG.md -->
|
||||
<!-- version: 19 -->
|
||||
<!-- version: 21 -->
|
||||
|
||||
# CHANGELOG — kb-lib
|
||||
|
||||
## 0.4.8-pre.005 — instructions Solana Program Metadata
|
||||
|
||||
- active `DcMetadataSolanaProgramMetadataDecoder` pour les neuf discriminants stables `0..8` ;
|
||||
- décode les arguments, comptes positionnels, signers, flags writable et sources inline ou Buffer avec des bornes explicites ;
|
||||
- conserve les formes runtime actuelles non produites par le SDK, notamment `SetData` sur trois octets et les suffixes ignorés de `SetImmutable`, `Trim` et `Close` ;
|
||||
- distingue comptes restants acceptés par le runtime et longueurs de comptes exactes ;
|
||||
- documente le nom pré-stable `WithdrawExcessLamports` du tag `5` sans créer une entrée historique distincte de `Trim` ;
|
||||
- ajoute la matrice d’instructions, l’audit historique, les tests positifs/négatifs et le test de façade publique ;
|
||||
- retire le décodeur Solana Program Metadata de l’inventaire des décodeurs réservés.
|
||||
- aligne la structure du composant sur les règles du workspace : façade limitée aux sous-modules et réexports, implémentation déplacée dans `decoder.rs`, constantes centralisées dans `constants.rs` et accès internes via `crate::`.
|
||||
- corrige les vecteurs négatifs `Initialize` afin de placer explicitement les valeurs invalides après les 16 octets du seed et de vérifier séparément `Encoding`, `Compression`, `Format` et `DataSource`.
|
||||
|
||||
## 0.4.8-pre.004 — comptes Solana Program Metadata
|
||||
|
||||
- ajoute les décodeurs publics bornés des comptes `Buffer` et `Metadata` ainsi que leur sélection par discriminateur ;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-lib/README.md -->
|
||||
<!-- version: 21 -->
|
||||
<!-- version: 22 -->
|
||||
|
||||
# kb-lib
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
## Périmètre
|
||||
|
||||
La crate couvre actuellement Solana Core, SPL Memo, SPL Token classique, SPL Associated Token Account, Token-2022, le registre SPL ElGamal et Metaplex Token Metadata. Elle expose également les modèles wire bornés et les décodeurs de comptes `Buffer` et `Metadata` de Solana Program Metadata ; le décodeur d’instructions reste réservé jusqu’à la phase suivante.
|
||||
La crate couvre actuellement Solana Core, SPL Memo, SPL Token classique, SPL Associated Token Account, Token-2022, le registre SPL ElGamal et Metaplex Token Metadata. Elle expose également les modèles wire bornés, les décodeurs de comptes `Buffer` et `Metadata` et le décodeur contextualisé des neuf instructions stables de Solana Program Metadata.
|
||||
|
||||
Pour Solana Program Metadata, la surface publique fondatrice comprend :
|
||||
|
||||
@@ -17,7 +17,10 @@ Pour Solana Program Metadata, la surface publique fondatrice comprend :
|
||||
- les données directes, URL et références vers un autre compte sans résolution off-chain ;
|
||||
- les cinq erreurs custom officielles et les erreurs de conversion fail-closed ;
|
||||
- les snapshots bornés `Buffer` et `Metadata`, avec validation du propriétaire, des PDA metadata, des longueurs logiques et des trois sources de données ;
|
||||
- une politique explicite où les octets situés après `data_length` sont conservés comme capacité allouée et jamais assimilés au contenu logique.
|
||||
- une politique explicite où les octets situés après `data_length` sont conservés comme capacité allouée et jamais assimilés au contenu logique ;
|
||||
- les neuf instructions stables `Write`, `Initialize`, `SetAuthority`, `SetData`, `SetImmutable`, `Trim`, `Close`, `Allocate` et `Extend` ;
|
||||
- les formes runtime actuelles non produites par le SDK, notamment `SetData` sans remplacement de données et les suffixes ignorés de `SetImmutable`, `Trim` et `Close` ;
|
||||
- une frontière historique où l’ancien nom pré-stable `WithdrawExcessLamports` du tag `5` reste une provenance de `Trim`, sans dixième entrée de couverture.
|
||||
|
||||
Pour Metaplex Token Metadata, elle fournit :
|
||||
|
||||
@@ -50,7 +53,7 @@ Pour Metaplex Token Metadata, elle fournit :
|
||||
- contrats `MtApi*` et matérialisateurs concrets ;
|
||||
- contrats `ExApi*`, politiques de sécurité et exécuteurs `Ex*Executor` ;
|
||||
- `ExMetadataMetaplexTokenMetadataExecutor`, `ExMetaplexTokenMetadataExecutionIntent` et `ExMetaplexTokenMetadataOperation` ;
|
||||
- modèles `DcMetadataSpm*`, constantes `DC_METADATA_SPM_*` et fonctions `decoder_metadata_solana_program_metadata_decode_*_account` pour le contrat Solana Program Metadata ;
|
||||
- `DcMetadataSolanaProgramMetadataDecoder`, modèles `DcMetadataSpm*`, constantes `DC_METADATA_SPM_*` et fonctions `decoder_metadata_solana_program_metadata_decode_*_account` pour le contrat Solana Program Metadata ;
|
||||
- modèles canoniques `Md*` réexportés par la façade.
|
||||
|
||||
Les exemples d’appel et invariants sont documentés dans [USAGE.md](USAGE.md).
|
||||
@@ -65,7 +68,7 @@ Les exemples d’appel et invariants sont documentés dans [USAGE.md](USAGE.md).
|
||||
|
||||
La surface fonctionnelle Metaplex de la crate est achevée. Les campagnes Devnet restantes relèvent de `kb-pipeline-demo-scenarios` et de `kb-app-demo-desktop`, non d’un manque de builder dans `kb-lib`.
|
||||
|
||||
Pour Solana Program Metadata, les modèles wire et les décodeurs bornés de comptes sont actifs. `Buffer` accepte tout reliquat comme données allouées sans inventer de PDA stable après changement d’autorité ; `Metadata` valide la dérivation canonical ou non-canonical et distingue le contenu logique de la capacité ajoutée par `Extend`. Le décodeur de protocole reste volontairement réservé jusqu’à l’implémentation des neuf instructions.
|
||||
Pour Solana Program Metadata, les modèles wire, les décodeurs bornés de comptes et le décodeur contextualisé des neuf instructions stables sont actifs. `Buffer` accepte tout reliquat comme données allouées sans inventer de PDA stable après changement d’autorité ; `Metadata` valide la dérivation canonical ou non-canonical et distingue le contenu logique de la capacité ajoutée par `Extend`. Les variantes qui dépendent de l’état du compte restent des intentions wire jusqu’aux lectures stateful prévues, et aucune forme pré-stable n’est déclarée compatible réseau sans preuve de cluster.
|
||||
|
||||
Le registre ElGamal n’est pas déclaré validé réellement sur réseau.
|
||||
|
||||
@@ -76,3 +79,5 @@ Le registre ElGamal n’est pas déclaré validé réellement sur réseau.
|
||||
- [Historique des changements](CHANGELOG.md)
|
||||
- [Matrice contractuelle Metaplex](../test-fixtures/contract-matrices/METAPLEX_TOKEN_METADATA_MATRIX.json)
|
||||
- [Matrice des comptes Solana Program Metadata](../test-fixtures/contract-matrices/SOLANA_PROGRAM_METADATA_ACCOUNT_MATRIX.json)
|
||||
- [Matrice des instructions Solana Program Metadata](../test-fixtures/contract-matrices/SOLANA_PROGRAM_METADATA_INSTRUCTION_MATRIX.json)
|
||||
- [Audit de l’inventaire et de l’historique des instructions](../docs/audits/V0_4_8_PRE_005_SOLANA_PROGRAM_METADATA_INSTRUCTION_HISTORY_AUDIT.md)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-lib/USAGE.md -->
|
||||
<!-- version: 10 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Utilisation de kb-lib
|
||||
|
||||
@@ -51,7 +51,8 @@ Décodeurs fonctionnels principaux :
|
||||
- `DcSplAssociatedTokenAccountDecoder` ;
|
||||
- `DcSplToken2022Decoder` ;
|
||||
- `DcSplElgamalRegistryDecoder` ;
|
||||
- `DcMetadataMetaplexTokenMetadataDecoder`.
|
||||
- `DcMetadataMetaplexTokenMetadataDecoder` ;
|
||||
- `DcMetadataSolanaProgramMetadataDecoder`.
|
||||
|
||||
Les types réservés `Dc*Decoder` ne doivent pas être interprétés comme des décodeurs complets : ils publient une compatibilité conservatrice et aucune observation fonctionnelle.
|
||||
|
||||
@@ -82,7 +83,7 @@ println!("parsed registry state: {registry:#?}");
|
||||
|
||||
Les parseurs vérifient les bornes et formats qu’ils annoncent. Ils ne reconstruisent pas un état historique depuis un RPC courant.
|
||||
|
||||
## Modèles et comptes Solana Program Metadata
|
||||
## Modèles, comptes et instructions Solana Program Metadata
|
||||
|
||||
Les modèles `DcMetadataSpm*` représentent uniquement le contrat on-chain du programme `ProgM6JCCvbYkfKqJYHePx4xxSUSqJp7rh8Lyv7nk7S`. Ils ne téléchargent jamais les URL et ne lisent pas automatiquement les comptes référencés par `External`.
|
||||
|
||||
@@ -138,7 +139,19 @@ match snapshot {
|
||||
|
||||
Une URL est seulement décodée comme chaîne UTF-8 on-chain. Aucune requête HTTP, IPFS ou Arweave n’est effectuée. Une référence `External` est seulement décodée en adresse, offset et longueur zeroable ; le compte référencé n’est pas lu.
|
||||
|
||||
Le décodeur de protocole `DcMetadataSolanaProgramMetadataDecoder` reste réservé aux instructions. Les comptes constituent désormais un contrat public stable pour les futurs matérialisateurs, builders et parcours stateful.
|
||||
Le décodeur `DcMetadataSolanaProgramMetadataDecoder` reconnaît le Program ID `ProgM6…` et les neuf tags stables `0..8`. Il conserve les différences utiles entre le wire SDK et le runtime actuel, sans interpréter un suffixe ignoré comme un nouvel argument.
|
||||
|
||||
```rust
|
||||
let decoder = kb_lib::DcMetadataSolanaProgramMetadataDecoder;
|
||||
let recognition = kb_lib::DcApiInstructionDecoder::recognize(&decoder, &input);
|
||||
if !recognition.compatible {
|
||||
return std::result::Result::Err("instruction incompatible".to_string());
|
||||
}
|
||||
let result = kb_lib::DcApiInstructionDecoder::decode(&decoder, &input);
|
||||
println!("status={:?}", result.status);
|
||||
```
|
||||
|
||||
Le tag `5` est toujours publié comme `trim`. Son ancien nom pré-stable `withdraw_excess_lamports` est conservé uniquement comme provenance, car aucune release stable ne l’expose comme instruction distincte. Les URL et références externes restent des données on-chain ; le décodeur ne réalise aucun fetch.
|
||||
|
||||
## Comptes Metaplex Token Metadata
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/decoder.rs
|
||||
// version: 14
|
||||
// version: 16
|
||||
|
||||
//! Consolidated decoder modules.
|
||||
|
||||
@@ -36,7 +36,6 @@ mod weighted;
|
||||
|
||||
/// Reserved `kb-lib.decoder.adapter.saber_decimal_wrapper` decoder.
|
||||
pub use self::adapter::DcAdapterSaberDecimalWrapperDecoder;
|
||||
/// Approve Collection Authority discriminator.
|
||||
/// Reserved `kb-lib.decoder.adapter.spl_token_wrap` decoder.
|
||||
pub use self::adapter::DcAdapterSplTokenWrapDecoder;
|
||||
/// Reserved `kb-lib.decoder.amm.aldrin_v1` decoder.
|
||||
@@ -201,6 +200,7 @@ pub use self::lending::DcLendingKaminoDecoder;
|
||||
pub use self::lending::DcLendingMarginfiV2Decoder;
|
||||
/// Reserved `kb-lib.decoder.lock.raydium_lp` decoder.
|
||||
pub use self::lock::DcLockRaydiumLpDecoder;
|
||||
/// Approve Collection Authority discriminator.
|
||||
pub(crate) use self::metadata::DC_METADATA_MTM_APPROVE_COLLECTION_AUTHORITY_DISCRIMINATOR;
|
||||
/// Approve Use Authority discriminator.
|
||||
pub(crate) use self::metadata::DC_METADATA_MTM_APPROVE_USE_AUTHORITY_DISCRIMINATOR;
|
||||
@@ -332,16 +332,50 @@ pub(crate) use self::metadata::DC_METADATA_MTM_VERIFY_COLLECTION_DISCRIMINATOR;
|
||||
pub(crate) use self::metadata::DC_METADATA_MTM_VERIFY_DISCRIMINATOR;
|
||||
/// Verify Sized Collection Item discriminator.
|
||||
pub(crate) use self::metadata::DC_METADATA_MTM_VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR;
|
||||
/// Account contract for `Allocate`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_ALLOCATE_ACCOUNT_CONTRACTS;
|
||||
/// Exact fixed byte length of one Buffer account header.
|
||||
pub use self::metadata::DC_METADATA_SPM_BUFFER_HEADER_BYTES;
|
||||
/// Account contract for `Close`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_CLOSE_ACCOUNT_CONTRACTS;
|
||||
/// Surfaces handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_DECODER_SURFACES;
|
||||
/// Maximum instruction prefix retained in hexadecimal diagnostics.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Stable event schema version for decoded Solana Program Metadata instructions.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_EVENT_VERSION;
|
||||
/// Account contract for `Extend`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_EXTEND_ACCOUNT_CONTRACTS;
|
||||
/// Exact byte length of one external-account data reference.
|
||||
pub use self::metadata::DC_METADATA_SPM_EXTERNAL_DATA_BYTES;
|
||||
/// Account contract for `Initialize`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_INITIALIZE_ACCOUNT_CONTRACTS;
|
||||
/// Current stable instruction inventory for program releases 1.0.0 and 1.0.1.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_INSTRUCTION_ENTRIES;
|
||||
/// Maximum Solana account-data length accepted by bounded account decoders.
|
||||
pub use self::metadata::DC_METADATA_SPM_MAX_ACCOUNT_BYTES;
|
||||
/// Maximum instruction-account count accepted by the contextual decoder.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_MAX_INSTRUCTION_ACCOUNTS;
|
||||
/// Maximum retained instruction payload accepted by the contextual decoder.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_MAX_INSTRUCTION_BYTES;
|
||||
/// Exact fixed byte length of one Metadata account header.
|
||||
pub use self::metadata::DC_METADATA_SPM_METADATA_HEADER_BYTES;
|
||||
/// Program ids handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_PROGRAM_IDS;
|
||||
/// Exact byte length of one Solana Program Metadata seed.
|
||||
pub use self::metadata::DC_METADATA_SPM_SEED_BYTES;
|
||||
/// Account contract for `SetAuthority`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_SET_AUTHORITY_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetData`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_SET_DATA_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetImmutable`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_SET_IMMUTABLE_ACCOUNT_CONTRACTS;
|
||||
/// Stable Solana Program Metadata decoder surface code.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_SURFACE_CODE;
|
||||
/// Account contract for `Trim`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_TRIM_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Write`.
|
||||
pub(crate) use self::metadata::DC_METADATA_SPM_WRITE_ACCOUNT_CONTRACTS;
|
||||
/// Exact decoder for the Metaplex Token Metadata program.
|
||||
pub use self::metadata::DcMetadataMetaplexTokenMetadataDecoder;
|
||||
/// Canonical projection shared by Collection and Use Authority records.
|
||||
@@ -414,6 +448,8 @@ pub use self::metadata::DcMetadataSpmEncoding;
|
||||
pub use self::metadata::DcMetadataSpmExternalData;
|
||||
/// Format declared for Solana Program Metadata content.
|
||||
pub use self::metadata::DcMetadataSpmFormat;
|
||||
/// Expected account role and privileges for one instruction position.
|
||||
pub(crate) use self::metadata::DcMetadataSpmInstructionAccountContract;
|
||||
/// Bounded projection of one initialized Solana Program Metadata account.
|
||||
pub use self::metadata::DcMetadataSpmMetadataAccountSnapshot;
|
||||
/// Bounded Solana Program Metadata model conversion error.
|
||||
@@ -424,6 +460,8 @@ pub use self::metadata::DcMetadataSpmProgramError;
|
||||
pub use self::metadata::DcMetadataSpmSeed;
|
||||
/// Canonical tracing target for this crate.
|
||||
pub(crate) use self::metadata::TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA;
|
||||
/// Canonical tracing target for the Solana Program Metadata decoder.
|
||||
pub(crate) use self::metadata::TRACING_TARGET_DECODER_METADATA_SOLANA_PROGRAM_METADATA;
|
||||
/// Crate-root access to `decode` from `instruction`.
|
||||
pub(crate) use self::metadata::decoder_metadata_metaplex_token_metadata_decode;
|
||||
/// Decodes one Collection Authority Record account.
|
||||
@@ -450,12 +488,18 @@ pub use self::metadata::decoder_metadata_metaplex_token_metadata_decode_use_auth
|
||||
pub(crate) use self::metadata::decoder_metadata_metaplex_token_metadata_entry_for_discriminator;
|
||||
/// Crate-root access to `payload_discriminator` from `instruction`.
|
||||
pub(crate) use self::metadata::decoder_metadata_metaplex_token_metadata_payload_discriminator;
|
||||
/// Decodes one bounded Solana Program Metadata instruction.
|
||||
pub(crate) use self::metadata::decoder_metadata_solana_program_metadata_decode;
|
||||
/// Decodes one supported Solana Program Metadata account by its discriminator.
|
||||
pub use self::metadata::decoder_metadata_solana_program_metadata_decode_account;
|
||||
/// Decodes one Solana Program Metadata Buffer account.
|
||||
pub use self::metadata::decoder_metadata_solana_program_metadata_decode_buffer_account;
|
||||
/// Decodes one initialized Solana Program Metadata account.
|
||||
pub use self::metadata::decoder_metadata_solana_program_metadata_decode_metadata_account;
|
||||
/// Returns the stable entry matching one Solana Program Metadata discriminator.
|
||||
pub(crate) use self::metadata::decoder_metadata_solana_program_metadata_entry_for_discriminator;
|
||||
/// Returns the first byte of one retained Solana Program Metadata payload.
|
||||
pub(crate) use self::metadata::decoder_metadata_solana_program_metadata_payload_discriminator;
|
||||
/// Reserved `kb-lib.decoder.nft.metaplex_bubblegum` decoder.
|
||||
pub use self::nft::DcNftMetaplexBubblegumDecoder;
|
||||
/// Reserved `kb-lib.decoder.nft.tensor_cnft` decoder.
|
||||
@@ -755,11 +799,10 @@ pub use self::weighted::DcWeightedSwapStabbleDecoder;
|
||||
mod reserved_decoder_tests {
|
||||
#[test]
|
||||
fn every_reserved_decoder_exposes_only_registered_program_ids() {
|
||||
let decoders: [&dyn crate::DcApiProtocolDecoder; 105] = [
|
||||
let decoders: [&dyn crate::DcApiProtocolDecoder; 104] = [
|
||||
&crate::DcAdapterSaberDecimalWrapperDecoder,
|
||||
&crate::DcAdapterSplTokenWrapDecoder,
|
||||
&crate::DcGovernanceSquadsMultisigDecoder,
|
||||
&crate::DcMetadataSolanaProgramMetadataDecoder,
|
||||
&crate::DcNftTensorCnftDecoder,
|
||||
&crate::DcPerpetualsPhoenixEternalDecoder,
|
||||
&crate::DcStakingJitoTipDistributionDecoder,
|
||||
@@ -891,6 +934,6 @@ mod reserved_decoder_tests {
|
||||
assert!(decode_result.is_ok_and(|events| return events.is_empty()));
|
||||
}
|
||||
}
|
||||
assert_eq!(names.len(), 105);
|
||||
assert_eq!(names.len(), 104);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/decoder/metadata.rs
|
||||
// version: 9
|
||||
// version: 11
|
||||
|
||||
//! `metadata` decoder family.
|
||||
|
||||
@@ -87,7 +87,7 @@ pub use self::solana_program_metadata::DC_METADATA_SPM_MAX_ACCOUNT_BYTES;
|
||||
pub use self::solana_program_metadata::DC_METADATA_SPM_METADATA_HEADER_BYTES;
|
||||
/// Exact byte length of one Solana Program Metadata seed.
|
||||
pub use self::solana_program_metadata::DC_METADATA_SPM_SEED_BYTES;
|
||||
/// Solana Program Metadata instruction decoder; account decoders are active.
|
||||
/// Exact Solana Program Metadata instruction and account decoder.
|
||||
pub use self::solana_program_metadata::DcMetadataSolanaProgramMetadataDecoder;
|
||||
/// Error returned while decoding a Solana Program Metadata account.
|
||||
pub use self::solana_program_metadata::DcMetadataSpmAccountDecodeError;
|
||||
@@ -264,3 +264,47 @@ pub(crate) use self::metaplex_token_metadata::decoder_metadata_metaplex_token_me
|
||||
pub(crate) use self::metaplex_token_metadata::decoder_metadata_metaplex_token_metadata_entry_for_discriminator;
|
||||
/// Crate-root access to `payload_discriminator` from `instruction`.
|
||||
pub(crate) use self::metaplex_token_metadata::decoder_metadata_metaplex_token_metadata_payload_discriminator;
|
||||
/// Account contract for `Allocate`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_ALLOCATE_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Close`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_CLOSE_ACCOUNT_CONTRACTS;
|
||||
/// Surfaces handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_DECODER_SURFACES;
|
||||
/// Maximum instruction prefix retained in hexadecimal diagnostics.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Stable event schema version for decoded Solana Program Metadata instructions.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_EVENT_VERSION;
|
||||
/// Account contract for `Extend`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_EXTEND_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Initialize`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_INITIALIZE_ACCOUNT_CONTRACTS;
|
||||
/// Current stable instruction inventory for program releases 1.0.0 and 1.0.1.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_INSTRUCTION_ENTRIES;
|
||||
/// Maximum instruction-account count accepted by the contextual decoder.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_MAX_INSTRUCTION_ACCOUNTS;
|
||||
/// Maximum retained instruction payload accepted by the contextual decoder.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_MAX_INSTRUCTION_BYTES;
|
||||
/// Program ids handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_PROGRAM_IDS;
|
||||
/// Account contract for `SetAuthority`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_SET_AUTHORITY_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetData`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_SET_DATA_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetImmutable`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_SET_IMMUTABLE_ACCOUNT_CONTRACTS;
|
||||
/// Stable Solana Program Metadata decoder surface code.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_SURFACE_CODE;
|
||||
/// Account contract for `Trim`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_TRIM_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Write`.
|
||||
pub(crate) use self::solana_program_metadata::DC_METADATA_SPM_WRITE_ACCOUNT_CONTRACTS;
|
||||
/// Expected account role and privileges for one instruction position.
|
||||
pub(crate) use self::solana_program_metadata::DcMetadataSpmInstructionAccountContract;
|
||||
/// Canonical tracing target for the Solana Program Metadata decoder.
|
||||
pub(crate) use self::solana_program_metadata::TRACING_TARGET_DECODER_METADATA_SOLANA_PROGRAM_METADATA;
|
||||
/// Decodes one bounded Solana Program Metadata instruction.
|
||||
pub(crate) use self::solana_program_metadata::decoder_metadata_solana_program_metadata_decode;
|
||||
/// Returns the stable entry matching one Solana Program Metadata discriminator.
|
||||
pub(crate) use self::solana_program_metadata::decoder_metadata_solana_program_metadata_entry_for_discriminator;
|
||||
/// Returns the first byte of one retained Solana Program Metadata payload.
|
||||
pub(crate) use self::solana_program_metadata::decoder_metadata_solana_program_metadata_payload_discriminator;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// file: kb-lib/src/decoder/metadata/solana_program_metadata.rs
|
||||
// version: 3
|
||||
// version: 5
|
||||
|
||||
//! Public Solana Program Metadata models, account decoders and reserved instruction decoder.
|
||||
//! Public Solana Program Metadata models and exact account and instruction decoders.
|
||||
|
||||
mod account;
|
||||
mod constants;
|
||||
mod decoder;
|
||||
mod instruction;
|
||||
mod model;
|
||||
|
||||
/// Error returned while decoding a Solana Program Metadata account.
|
||||
@@ -31,6 +33,8 @@ pub use self::constants::DC_METADATA_SPM_MAX_ACCOUNT_BYTES;
|
||||
pub use self::constants::DC_METADATA_SPM_METADATA_HEADER_BYTES;
|
||||
/// Exact byte length of one Solana Program Metadata seed.
|
||||
pub use self::constants::DC_METADATA_SPM_SEED_BYTES;
|
||||
/// Exact decoder for Solana Program Metadata instructions and account snapshots.
|
||||
pub use self::decoder::DcMetadataSolanaProgramMetadataDecoder;
|
||||
/// Solana Program Metadata account discriminator.
|
||||
pub use self::model::DcMetadataSpmAccountDiscriminator;
|
||||
/// Compression declared for metadata content.
|
||||
@@ -52,37 +56,47 @@ pub use self::model::DcMetadataSpmProgramError;
|
||||
/// Exact fixed-size metadata seed.
|
||||
pub use self::model::DcMetadataSpmSeed;
|
||||
|
||||
/// Decoder reserved for Solana Program Metadata instructions; account decoding is exposed separately.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct DcMetadataSolanaProgramMetadataDecoder;
|
||||
|
||||
impl crate::DcApiProtocolDecoder for crate::DcMetadataSolanaProgramMetadataDecoder {
|
||||
fn decoder_name(&self) -> &'static str {
|
||||
return "kb-lib.decoder.metadata.solana_program_metadata";
|
||||
}
|
||||
|
||||
fn decoder_version(&self) -> &'static str {
|
||||
return env!("CARGO_PKG_VERSION");
|
||||
}
|
||||
|
||||
fn program_ids(&self) -> &'static [&'static str] {
|
||||
return &[kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID];
|
||||
}
|
||||
|
||||
fn supports_observation(
|
||||
&self,
|
||||
observation: &crate::MdProgramObservation,
|
||||
) -> crate::DcApiDecoderSupport {
|
||||
if crate::DcApiProtocolDecoder::handles_program_id(self, &observation.program_id) {
|
||||
return crate::DcApiDecoderSupport::Maybe;
|
||||
}
|
||||
return crate::DcApiDecoderSupport::No;
|
||||
}
|
||||
|
||||
fn decode_observation(
|
||||
&self,
|
||||
_observation: &crate::MdProgramObservation,
|
||||
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
|
||||
return std::result::Result::Ok(std::vec::Vec::new());
|
||||
}
|
||||
}
|
||||
/// Account contract for `Allocate`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_ALLOCATE_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Close`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_CLOSE_ACCOUNT_CONTRACTS;
|
||||
/// Surfaces handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_DECODER_SURFACES;
|
||||
/// Maximum instruction prefix retained in hexadecimal diagnostics.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Stable event schema version for decoded Solana Program Metadata instructions.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_EVENT_VERSION;
|
||||
/// Account contract for `Extend`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_EXTEND_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Initialize`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_INITIALIZE_ACCOUNT_CONTRACTS;
|
||||
/// Current stable instruction inventory for program releases 1.0.0 and 1.0.1.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_INSTRUCTION_ENTRIES;
|
||||
/// Maximum instruction-account count accepted by the contextual decoder.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_MAX_INSTRUCTION_ACCOUNTS;
|
||||
/// Maximum retained instruction payload accepted by the contextual decoder.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_MAX_INSTRUCTION_BYTES;
|
||||
/// Program ids handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_PROGRAM_IDS;
|
||||
/// Account contract for `SetAuthority`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_SET_AUTHORITY_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetData`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_SET_DATA_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetImmutable`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_SET_IMMUTABLE_ACCOUNT_CONTRACTS;
|
||||
/// Stable Solana Program Metadata decoder surface code.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_SURFACE_CODE;
|
||||
/// Account contract for `Trim`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_TRIM_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Write`.
|
||||
pub(crate) use self::constants::DC_METADATA_SPM_WRITE_ACCOUNT_CONTRACTS;
|
||||
/// Expected account role and privileges for one instruction position.
|
||||
pub(crate) use self::constants::DcMetadataSpmInstructionAccountContract;
|
||||
/// Canonical tracing target for the Solana Program Metadata decoder.
|
||||
pub(crate) use self::constants::TRACING_TARGET_DECODER_METADATA_SOLANA_PROGRAM_METADATA;
|
||||
/// Decodes one bounded Solana Program Metadata instruction.
|
||||
pub(crate) use self::instruction::decoder_metadata_solana_program_metadata_decode;
|
||||
/// Returns the stable entry matching one Solana Program Metadata discriminator.
|
||||
pub(crate) use self::instruction::decoder_metadata_solana_program_metadata_entry_for_discriminator;
|
||||
/// Returns the first byte of one retained Solana Program Metadata payload.
|
||||
pub(crate) use self::instruction::decoder_metadata_solana_program_metadata_payload_discriminator;
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
// file: kb-lib/src/decoder/metadata/solana_program_metadata/constants.rs
|
||||
// version: 2
|
||||
// version: 4
|
||||
|
||||
//! Bounded Solana Program Metadata wire constants.
|
||||
//! Bounded Solana Program Metadata wire and decoder constants.
|
||||
|
||||
/// Expected account role and privileges for one instruction position.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) struct DcMetadataSpmInstructionAccountContract {
|
||||
pub(crate) role: &'static str,
|
||||
pub(crate) signer: bool,
|
||||
pub(crate) writable: bool,
|
||||
pub(crate) optional: bool,
|
||||
}
|
||||
|
||||
/// Exact byte length of one Solana Program Metadata seed.
|
||||
pub const DC_METADATA_SPM_SEED_BYTES: usize = 16;
|
||||
@@ -13,3 +22,320 @@ pub const DC_METADATA_SPM_METADATA_HEADER_BYTES: usize = 96;
|
||||
pub const DC_METADATA_SPM_EXTERNAL_DATA_BYTES: usize = 40;
|
||||
/// Maximum Solana account-data length accepted by bounded account decoders.
|
||||
pub const DC_METADATA_SPM_MAX_ACCOUNT_BYTES: usize = 10_485_760;
|
||||
/// Maximum retained instruction payload accepted by the contextual decoder.
|
||||
pub(crate) const DC_METADATA_SPM_MAX_INSTRUCTION_BYTES: usize = 16_384;
|
||||
/// Maximum instruction-account count accepted by the contextual decoder.
|
||||
pub(crate) const DC_METADATA_SPM_MAX_INSTRUCTION_ACCOUNTS: usize = 16;
|
||||
/// Maximum instruction prefix retained in hexadecimal diagnostics.
|
||||
pub(crate) const DC_METADATA_SPM_DIAGNOSTIC_PREFIX_BYTES: usize = 64;
|
||||
/// Stable Solana Program Metadata decoder surface code.
|
||||
pub(crate) const DC_METADATA_SPM_SURFACE_CODE: &str = "metadata.solana_program_metadata";
|
||||
/// Stable event schema version for decoded Solana Program Metadata instructions.
|
||||
pub(crate) const DC_METADATA_SPM_EVENT_VERSION: u16 = 1;
|
||||
/// Current stable instruction inventory for program releases 1.0.0 and 1.0.1.
|
||||
pub(crate) const DC_METADATA_SPM_INSTRUCTION_ENTRIES: &[(u8, &str)] = &[
|
||||
(0, "write"),
|
||||
(1, "initialize"),
|
||||
(2, "set_authority"),
|
||||
(3, "set_data"),
|
||||
(4, "set_immutable"),
|
||||
(5, "trim"),
|
||||
(6, "close"),
|
||||
(7, "allocate"),
|
||||
(8, "extend"),
|
||||
];
|
||||
/// Program ids handled by the Solana Program Metadata decoder.
|
||||
pub(crate) const DC_METADATA_SPM_PROGRAM_IDS: &[&str] =
|
||||
&[kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID];
|
||||
/// Surfaces handled by the Solana Program Metadata decoder.
|
||||
pub(crate) const DC_METADATA_SPM_DECODER_SURFACES: &[crate::DcApiDecoderSurface] =
|
||||
&[crate::DcApiDecoderSurface {
|
||||
program_id: kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID,
|
||||
surface_code: crate::DC_METADATA_SPM_SURFACE_CODE,
|
||||
priority: 100,
|
||||
}];
|
||||
/// Account contract for `Write`.
|
||||
pub(crate) const DC_METADATA_SPM_WRITE_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "buffer",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "source_buffer",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
];
|
||||
/// Account contract for `Initialize`.
|
||||
pub(crate) const DC_METADATA_SPM_INITIALIZE_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "metadata",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "system_program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
];
|
||||
/// Account contract for `SetAuthority`.
|
||||
pub(crate) const DC_METADATA_SPM_SET_AUTHORITY_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "account",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
];
|
||||
/// Account contract for `SetData`.
|
||||
pub(crate) const DC_METADATA_SPM_SET_DATA_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "metadata",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "buffer",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
];
|
||||
/// Account contract for `SetImmutable`.
|
||||
pub(crate) const DC_METADATA_SPM_SET_IMMUTABLE_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "metadata",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
];
|
||||
/// Account contract for `Trim`.
|
||||
pub(crate) const DC_METADATA_SPM_TRIM_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "account",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "destination",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "rent_sysvar",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
];
|
||||
/// Account contract for `Close`.
|
||||
pub(crate) const DC_METADATA_SPM_CLOSE_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "account",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "destination",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
];
|
||||
/// Account contract for `Allocate`.
|
||||
pub(crate) const DC_METADATA_SPM_ALLOCATE_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "buffer",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "system_program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
];
|
||||
/// Account contract for `Extend`.
|
||||
pub(crate) const DC_METADATA_SPM_EXTEND_ACCOUNT_CONTRACTS:
|
||||
&[crate::DcMetadataSpmInstructionAccountContract] = &[
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "account",
|
||||
signer: false,
|
||||
writable: true,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "authority",
|
||||
signer: true,
|
||||
writable: false,
|
||||
optional: false,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
crate::DcMetadataSpmInstructionAccountContract {
|
||||
role: "program_data",
|
||||
signer: false,
|
||||
writable: false,
|
||||
optional: true,
|
||||
},
|
||||
];
|
||||
/// Canonical tracing target for the Solana Program Metadata decoder.
|
||||
pub(crate) const TRACING_TARGET_DECODER_METADATA_SOLANA_PROGRAM_METADATA: &str =
|
||||
"kb-lib.decoder.metadata.solana_program_metadata";
|
||||
|
||||
134
kb-lib/src/decoder/metadata/solana_program_metadata/decoder.rs
Normal file
134
kb-lib/src/decoder/metadata/solana_program_metadata/decoder.rs
Normal file
@@ -0,0 +1,134 @@
|
||||
// file: kb-lib/src/decoder/metadata/solana_program_metadata/decoder.rs
|
||||
// version: 1
|
||||
|
||||
//! Exact contextual dispatch for Solana Program Metadata.
|
||||
|
||||
/// Exact decoder for Solana Program Metadata instructions and account snapshots.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct DcMetadataSolanaProgramMetadataDecoder;
|
||||
|
||||
impl crate::DcApiProtocolDecoder for crate::DcMetadataSolanaProgramMetadataDecoder {
|
||||
fn decoder_name(&self) -> &'static str {
|
||||
return "kb-lib.decoder.metadata.solana_program_metadata";
|
||||
}
|
||||
|
||||
fn decoder_version(&self) -> &'static str {
|
||||
return env!("CARGO_PKG_VERSION");
|
||||
}
|
||||
|
||||
fn program_ids(&self) -> &'static [&'static str] {
|
||||
return crate::DC_METADATA_SPM_PROGRAM_IDS;
|
||||
}
|
||||
|
||||
fn supports_observation(
|
||||
&self,
|
||||
observation: &crate::MdProgramObservation,
|
||||
) -> crate::DcApiDecoderSupport {
|
||||
return if crate::DcApiProtocolDecoder::handles_program_id(self, &observation.program_id) {
|
||||
crate::DcApiDecoderSupport::Yes
|
||||
} else {
|
||||
crate::DcApiDecoderSupport::No
|
||||
};
|
||||
}
|
||||
|
||||
fn decode_observation(
|
||||
&self,
|
||||
_observation: &crate::MdProgramObservation,
|
||||
) -> kb_core::Result<std::vec::Vec<crate::MdDecodedProtocolEvent>> {
|
||||
return std::result::Result::Ok(std::vec::Vec::new());
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::DcApiInstructionDecoder for crate::DcMetadataSolanaProgramMetadataDecoder {
|
||||
fn identity(&self) -> crate::DcApiDecoderIdentity {
|
||||
return crate::DcApiDecoderIdentity {
|
||||
name: crate::DC_METADATA_SPM_SURFACE_CODE.to_string(),
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
};
|
||||
}
|
||||
|
||||
fn surfaces(&self) -> &'static [crate::DcApiDecoderSurface] {
|
||||
return crate::DC_METADATA_SPM_DECODER_SURFACES;
|
||||
}
|
||||
|
||||
fn coverage(&self) -> std::vec::Vec<crate::DcApiDecoderCoverageDeclaration> {
|
||||
return crate::DC_METADATA_SPM_INSTRUCTION_ENTRIES
|
||||
.iter()
|
||||
.map(|(tag, code)| {
|
||||
return crate::DcApiDecoderCoverageDeclaration {
|
||||
program_id: kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID
|
||||
.to_string(),
|
||||
surface_code: std::option::Option::Some(
|
||||
crate::DC_METADATA_SPM_SURFACE_CODE.to_string(),
|
||||
),
|
||||
entry_kind: crate::DcApiDecoderCoverageEntryKind::Instruction,
|
||||
entry_code: (*code).to_string(),
|
||||
discriminator_hex: std::option::Option::Some(format!("{tag:02x}")),
|
||||
historical: false,
|
||||
};
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
fn recognize(
|
||||
&self,
|
||||
input: &crate::MdCoreInstructionReplayInput,
|
||||
) -> crate::DcApiDecoderRecognition {
|
||||
if input.program_id != kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID {
|
||||
return crate::DcApiDecoderRecognition::incompatible();
|
||||
}
|
||||
let discriminator =
|
||||
crate::decoder_metadata_solana_program_metadata_payload_discriminator(input);
|
||||
let entry = discriminator
|
||||
.and_then(crate::decoder_metadata_solana_program_metadata_entry_for_discriminator);
|
||||
return crate::DcApiDecoderRecognition::compatible(
|
||||
entry.is_some(),
|
||||
100,
|
||||
std::option::Option::Some(crate::DC_METADATA_SPM_SURFACE_CODE.to_string()),
|
||||
entry.map(|(_, code)| return code.to_string()),
|
||||
discriminator.map(|value| return format!("{value:02x}")),
|
||||
);
|
||||
}
|
||||
|
||||
fn decode(
|
||||
&self,
|
||||
input: &crate::MdCoreInstructionReplayInput,
|
||||
) -> crate::DcApiDecoderExecutionResult {
|
||||
if input.program_id != kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID {
|
||||
return crate::DcApiDecoderExecutionResult::unsupported(std::option::Option::None);
|
||||
}
|
||||
let result = crate::decoder_metadata_solana_program_metadata_decode(input);
|
||||
if matches!(
|
||||
result.status,
|
||||
crate::DcApiDecoderOutcomeStatus::Failed
|
||||
| crate::DcApiDecoderOutcomeStatus::Unsupported
|
||||
) {
|
||||
tracing::error!(
|
||||
target: crate::TRACING_TARGET_DECODER_METADATA_SOLANA_PROGRAM_METADATA,
|
||||
action = "decode_failure",
|
||||
signature = %input.signature,
|
||||
slot = input.slot,
|
||||
instruction_path = %input.instruction_path,
|
||||
program_id = %input.program_id,
|
||||
processor_name = crate::DC_METADATA_SPM_SURFACE_CODE,
|
||||
processor_version = env!("CARGO_PKG_VERSION"),
|
||||
input_key = %input.replay_input_key,
|
||||
transaction_failed = input.transaction_failed,
|
||||
result_status = ?result.status,
|
||||
diagnostics = ?result.diagnostics,
|
||||
"Solana Program Metadata instruction was not decoded successfully"
|
||||
);
|
||||
}
|
||||
tracing::debug!(
|
||||
target: crate::TRACING_TARGET_DECODER_METADATA_SOLANA_PROGRAM_METADATA,
|
||||
action = "decode",
|
||||
signature = %input.signature,
|
||||
instruction_path = %input.instruction_path,
|
||||
transaction_failed = input.transaction_failed,
|
||||
result_status = ?result.status,
|
||||
observation_count = result.observations.len(),
|
||||
"Solana Program Metadata instruction decode completed"
|
||||
);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
1282
kb-lib/src/decoder/metadata/solana_program_metadata/instruction.rs
Normal file
1282
kb-lib/src/decoder/metadata/solana_program_metadata/instruction.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/lib.rs
|
||||
// version: 31
|
||||
// version: 32
|
||||
|
||||
//! Consolidated decoder, executor, materializer and shared model library.
|
||||
#![warn(missing_docs)]
|
||||
@@ -29,7 +29,6 @@ pub use self::decoder::DC_METADATA_SPM_SEED_BYTES;
|
||||
pub use self::decoder::DC_SPL_ELGAMAL_REGISTRY_ACCOUNT_LEN;
|
||||
/// Reserved `kb-lib.decoder.adapter.saber_decimal_wrapper` decoder.
|
||||
pub use self::decoder::DcAdapterSaberDecimalWrapperDecoder;
|
||||
/// Approve Collection Authority discriminator.
|
||||
/// Exposes the reserved `DcAdapterSplTokenWrapDecoder` implementation.
|
||||
pub use self::decoder::DcAdapterSplTokenWrapDecoder;
|
||||
/// Reserved `kb-lib.decoder.amm.aldrin_v1` decoder.
|
||||
@@ -1641,6 +1640,40 @@ pub(crate) use self::decoder::DC_METADATA_MTM_VERIFY_COLLECTION_DISCRIMINATOR;
|
||||
pub(crate) use self::decoder::DC_METADATA_MTM_VERIFY_DISCRIMINATOR;
|
||||
/// Verify Sized Collection Item discriminator.
|
||||
pub(crate) use self::decoder::DC_METADATA_MTM_VERIFY_SIZED_COLLECTION_ITEM_DISCRIMINATOR;
|
||||
/// Account contract for `Allocate`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_ALLOCATE_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Close`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_CLOSE_ACCOUNT_CONTRACTS;
|
||||
/// Surfaces handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_DECODER_SURFACES;
|
||||
/// Maximum instruction prefix retained in hexadecimal diagnostics.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Stable event schema version for decoded Solana Program Metadata instructions.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_EVENT_VERSION;
|
||||
/// Account contract for `Extend`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_EXTEND_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Initialize`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_INITIALIZE_ACCOUNT_CONTRACTS;
|
||||
/// Current stable instruction inventory for program releases 1.0.0 and 1.0.1.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_INSTRUCTION_ENTRIES;
|
||||
/// Maximum instruction-account count accepted by the contextual decoder.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_MAX_INSTRUCTION_ACCOUNTS;
|
||||
/// Maximum retained instruction payload accepted by the contextual decoder.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_MAX_INSTRUCTION_BYTES;
|
||||
/// Program ids handled by the Solana Program Metadata decoder.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_PROGRAM_IDS;
|
||||
/// Account contract for `SetAuthority`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_SET_AUTHORITY_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetData`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_SET_DATA_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `SetImmutable`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_SET_IMMUTABLE_ACCOUNT_CONTRACTS;
|
||||
/// Stable Solana Program Metadata decoder surface code.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_SURFACE_CODE;
|
||||
/// Account contract for `Trim`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_TRIM_ACCOUNT_CONTRACTS;
|
||||
/// Account contract for `Write`.
|
||||
pub(crate) use self::decoder::DC_METADATA_SPM_WRITE_ACCOUNT_CONTRACTS;
|
||||
/// Stable Address Lookup Table surface code.
|
||||
pub(crate) use self::decoder::DC_SOLANA_CORE_ADDRESS_LOOKUP_TABLE_SURFACE_CODE;
|
||||
/// Stable deprecated immutable BPF Loader surface code.
|
||||
@@ -1765,6 +1798,8 @@ pub(crate) use self::decoder::DC_SPL_TOKEN_MAX_BATCH_INSTRUCTIONS;
|
||||
pub(crate) use self::decoder::DC_SPL_TOKEN_MAX_INSTRUCTION_BYTES;
|
||||
/// Stable protocol and surface code for the classic SPL Token program.
|
||||
pub(crate) use self::decoder::DC_SPL_TOKEN_SURFACE_CODE;
|
||||
/// Expected account role and privileges for one instruction position.
|
||||
pub(crate) use self::decoder::DcMetadataSpmInstructionAccountContract;
|
||||
/// Expected role and privileges for one positional instruction account.
|
||||
pub(crate) use self::decoder::DcSolanaCoreAccountRole;
|
||||
/// One resolved outer instruction payload and its provenance relative to the target instruction.
|
||||
@@ -1773,6 +1808,8 @@ pub(crate) use self::decoder::DcSolanaCoreResolvedInstructionPayload;
|
||||
pub(crate) use self::decoder::DcSplElGamalRegistryParsedRegistryInstruction;
|
||||
/// Canonical tracing target for this crate.
|
||||
pub(crate) use self::decoder::TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA;
|
||||
/// Canonical tracing target for the Solana Program Metadata decoder.
|
||||
pub(crate) use self::decoder::TRACING_TARGET_DECODER_METADATA_SOLANA_PROGRAM_METADATA;
|
||||
/// Canonical tracing target for this crate.
|
||||
pub(crate) use self::decoder::TRACING_TARGET_DECODER_SOLANA_CORE;
|
||||
/// Canonical tracing target for the Associated Token Account decoder.
|
||||
@@ -1791,6 +1828,12 @@ pub(crate) use self::decoder::decoder_metadata_metaplex_token_metadata_decode;
|
||||
pub(crate) use self::decoder::decoder_metadata_metaplex_token_metadata_entry_for_discriminator;
|
||||
/// Crate-root access to `payload_discriminator` from `instruction`.
|
||||
pub(crate) use self::decoder::decoder_metadata_metaplex_token_metadata_payload_discriminator;
|
||||
/// Decodes one bounded Solana Program Metadata instruction.
|
||||
pub(crate) use self::decoder::decoder_metadata_solana_program_metadata_decode;
|
||||
/// Returns the stable entry matching one Solana Program Metadata discriminator.
|
||||
pub(crate) use self::decoder::decoder_metadata_solana_program_metadata_entry_for_discriminator;
|
||||
/// Returns the first byte of one retained Solana Program Metadata payload.
|
||||
pub(crate) use self::decoder::decoder_metadata_solana_program_metadata_payload_discriminator;
|
||||
/// Returns declared Address Lookup Table instruction coverage.
|
||||
pub(crate) use self::decoder::decoder_solana_core_address_lookup_table_coverage;
|
||||
/// Decodes one Address Lookup Table instruction.
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// file: kb-lib/tests/external_solana_program_metadata_instruction_api.rs
|
||||
// version: 1
|
||||
|
||||
//! Downstream-style compilation contract for the Solana Program Metadata instruction decoder.
|
||||
|
||||
#[test]
|
||||
fn external_consumers_decode_instructions_only_through_crate_root_exports() {
|
||||
let account = solana_pubkey::Pubkey::new_from_array([31_u8; 32]).to_string();
|
||||
let authority = solana_pubkey::Pubkey::new_from_array([32_u8; 32]).to_string();
|
||||
let placeholder = kb_program_ids::METADATA_SOLANA_PROGRAM_METADATA_PROGRAM_ID;
|
||||
let account_keys = serde_json::json!([
|
||||
{
|
||||
"accountIndex": 0,
|
||||
"accountKey": account,
|
||||
"source": "static",
|
||||
"signer": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"accountIndex": 1,
|
||||
"accountKey": authority,
|
||||
"source": "static",
|
||||
"signer": true,
|
||||
"writable": false
|
||||
},
|
||||
{
|
||||
"accountIndex": 2,
|
||||
"accountKey": placeholder,
|
||||
"source": "static",
|
||||
"signer": false,
|
||||
"writable": false
|
||||
},
|
||||
{
|
||||
"accountIndex": 3,
|
||||
"accountKey": placeholder,
|
||||
"source": "static",
|
||||
"signer": false,
|
||||
"writable": false
|
||||
}
|
||||
]);
|
||||
let instruction_accounts = serde_json::json!([
|
||||
{"accountIndex": 0, "accountKey": account},
|
||||
{"accountIndex": 1, "accountKey": authority},
|
||||
{"accountIndex": 2, "accountKey": placeholder},
|
||||
{"accountIndex": 3, "accountKey": placeholder}
|
||||
]);
|
||||
let input_result = kb_lib::MdCoreInstructionReplayInput::new(
|
||||
"spm:external:extend",
|
||||
"signature",
|
||||
42,
|
||||
"0",
|
||||
placeholder,
|
||||
false,
|
||||
std::option::Option::None,
|
||||
account_keys,
|
||||
instruction_accounts,
|
||||
std::option::Option::Some(serde_json::json!({"dataBase64": "CAEA"})),
|
||||
std::option::Option::None,
|
||||
serde_json::json!([]),
|
||||
serde_json::json!([]),
|
||||
serde_json::json!([]),
|
||||
serde_json::json!([]),
|
||||
);
|
||||
assert!(input_result.is_ok());
|
||||
let input: kb_lib::MdCoreInstructionReplayInput;
|
||||
if let std::result::Result::Ok(value) = input_result {
|
||||
input = value;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
let decoder = kb_lib::DcMetadataSolanaProgramMetadataDecoder;
|
||||
let recognition = kb_lib::DcApiInstructionDecoder::recognize(&decoder, &input);
|
||||
assert!(recognition.compatible);
|
||||
assert!(recognition.exact);
|
||||
assert_eq!(recognition.entry_code.as_deref(), std::option::Option::Some("extend"));
|
||||
let result = kb_lib::DcApiInstructionDecoder::decode(&decoder, &input);
|
||||
assert_eq!(result.status, kb_lib::DcApiDecoderOutcomeStatus::Decoded);
|
||||
assert_eq!(result.recognized_entry_code.as_deref(), std::option::Option::Some("extend"));
|
||||
assert_eq!(result.observations.len(), 1);
|
||||
assert_eq!(result.observations[0].payload_json["parameters"]["length"], 1);
|
||||
}
|
||||
Reference in New Issue
Block a user