Files
khadhroony-bot3/olddocs/archivekbot2/docs/CORE_EXTRACTION_CONTRACTS.md
2026-07-30 17:50:29 +02:00

6.4 KiB
Raw Permalink Blame History

Contrats dextraction core Solana

État de clôture 0.3.4-pre.011

Le jalon transforme une transaction canonique déjà persistée en graphe core normalisé et rejouable :

kb_sol_raw_transactions.canonical_json
  -> kb_model::CanonicalTransaction
    -> validation version/signature/slot/hash
      -> kb_pipeline::extract_raw_transaction_to_core
        -> CoreExtractionBundle
          -> transaction PostgreSQL atomique

Le payload fournisseur contenu à lorigine dans une réponse RPC nest jamais relu depuis les observations. La seule source fonctionnelle de lextracteur est le document canonique de kb_sol_raw_transactions.

Unité atomique

Une signature produit un CoreExtractionBundle contenant :

  • une transaction core liée par raw_transaction_id ;
  • les account keys statiques et chargées par ALT ;
  • les instructions top-level ;
  • les inner instructions ;
  • les logs ordonnés ;
  • les changements de balances natifs et token ;
  • lidentité du processor dans le ledger.

Le repository PostgreSQL supprime puis recrée le graphe de la signature dans une transaction unique. Un échec avant le commit laisse intact létat précédemment validé. Le test PostgreSQL de clôture provoque volontairement une violation dunicité après insertion de la transaction et dune première account key, puis vérifie labsence totale de graphe partiel, de changement raw et de succès ledger.

Validation de lentrée

Lextraction refuse explicitement :

  • un canonical_json absent ;
  • un canonical_json_hash absent ;
  • une version différente de CANONICAL_TRANSACTION_FORMAT_VERSION ;
  • un JSON non désérialisable en CanonicalTransaction ;
  • une signature ou un slot différent de la ligne raw ;
  • un hash recalculé différent du hash stocké ;
  • un indice de programme ou de compte hors de lespace résolu.

Lidentité du ledger est :

stage             = core_extraction
processor_name    = canonical_to_core
processor_version = 1
input_key         = signature
input_hash        = canonical_json_hash

Account keys

Lespace dindices est construit strictement dans cet ordre :

static account keys
loaded writable addresses
loaded readonly addresses

Pour les comptes statiques, les flags signer et writable sont dérivés du header Solana. Les loaded writable sont non-signers et writable. Les loaded readonly sont non-signers et readonly. executable reste NULL, car cette information nest pas contenue de manière fiable dans le contrat canonique actuel.

Instructions

Les chemins sont déterministes :

0
1
2
0/0
0/1
2/0

accounts_json conserve, dans lordre original, chaque indice et la clé publique résolue. payload_json conserve programIdIndex, dataBase64 et stackHeight. Un SHA-256 stable du payload JSON est persisté dans payload_json_hash.

Logs

Chaque log conserve :

  • son log_index global ;
  • son texte original ;
  • un SHA-256 du texte ;
  • un program_id et un instruction_path uniquement lorsque la pile invoke/success/failed permet un rattachement déterministe.

Lorsque la reconstruction est ambiguë, le lien reste NULL plutôt que dinventer une relation.

Balances

Les changements natifs utilisent les valeurs entières en lamports et stockent pre, post et delta comme chaînes décimales dans JSONB afin déviter toute perte de précision.

Les changements SPL et Token-2022 utilisent exclusivement amount et decimals. Les valeurs UI du fournisseur ne sont pas utilisées comme source de calcul. Pour un compte créé ou fermé pendant la transaction, le côté absent est représenté explicitement par un montant brut nul avec les mêmes décimales.

Le balance_change_index est déterministe : balances natives par index de compte, puis balances token triées par (account_index, mint, program_id).

Modes de sélection

La campagne peut sélectionner des transactions raw par signatures explicites, état received, plage de slots ou programme déjà présent dans les instructions top-level core. Les filtres, limites et scénarios de validation sont détaillés dans docs/CORE_EXTRACTION_SELECTION_AND_REPLAY.md.

Le mode par programme ne découvre pas un programme nouveau : il dépend des lignes déjà présentes dans kb_sol_core_instructions et ne couvre pas actuellement les occurrences exclusivement inner.

Idempotence et replay

En mode normal, une entrée ledger succeeded ayant la même version et le même hash provoque un skip.

Un changement de version ou de hash entraîne une nouvelle extraction. Le mode force_replay ignore le skip et remplace atomiquement le graphe existant de la signature.

Orchestration

kb_pipeline::execute_core_extraction fournit :

  • sélection par signatures ;
  • lot raw en état received ;
  • plage de slots ;
  • replay par program id déjà présent dans core ;
  • limite et concurrence bornées ;
  • arrêt coopératif avant admission de nouveaux candidats ;
  • résumé selected, started, completed, skipped, extracted, failed, cancelled_candidates et not_started.

La logique de transformation ne dépend ni de Tauri ni dun décodeur protocolaire.

Transactions échouées

Une transaction Solana ayant failed = true reste extraite intégralement lorsque ses métadonnées sont disponibles. Les instructions, inner instructions et logs exécutés avant lerreur constituent des observations utiles pour les futurs décodeurs.

Le futur pipeline doit distinguer :

observation décodée dans une transaction échouée
mutation détat confirmée dans une transaction réussie

Une transaction échouée peut produire des observations dintention, de cause déchec, de compute budget ou de surface appelée. Elle ne doit pas produire automatiquement un trade, une modification de liquidité ou une candle présentés comme réussis.

Validation réelle

Le skip et le force replay ont été validés sur 14 signatures : 14 skipped, puis 14 extracted avec force replay, puis 14 skipped. Les tables core restent à 70 transactions et le ledger totalise 84 tentatives. Les requêtes sql/validation/000_core_integrity.sql ne retournent aucune anomalie.

Hors périmètre

0.3.4 neffectue aucun décodage Solana Core/SPL, aucun décodage DEX, aucune matérialisation métier et aucune compaction du JSON canonique.