Files
khadhroony-bot3/olddocs/INSTRUCTION_REPLAY_CONTRACTS.md
2026-07-28 18:41:30 +02:00

4.9 KiB

Contrats de replay par instruction

Ce document complète le cadrage 0.2.1. Il ne crée pas encore le schéma SQL complet, mais il verrouille l'idée suivante : le scheduling de replay doit cibler les instructions normalisées, tandis que le décodage doit recevoir une instruction avec son contexte Solana extrait.

Motivation

Une transaction Solana peut contenir plusieurs instructions top-level et plusieurs inner instructions. Certaines instructions peuvent être déjà décodées, d'autres non. Rejouer toute la transaction à chaque correction de décodeur serait plus coûteux et moins précis.

Le pipeline doit donc pouvoir faire :

raw transaction
→ extraction core transaction
→ extraction account keys, instructions, inner instructions, logs, balances
→ sélection des instructions non traitées
→ reconstruction d'un replay input contextualisé
→ decode/materialize uniquement sur ces inputs

Scheduling instruction-level

L'état CoreInstructionProcessingState prépare cette granularité.

État Sens
Pending Instruction disponible pour premier traitement.
Decoded Instruction décodée par au moins un décodeur.
Materialized Instruction ayant produit une projection métier.
Ignored Instruction ignorée volontairement par la politique courante.
Failed Instruction en échec, à diagnostiquer.
ReplayRequested Instruction à rejouer même si un traitement précédent existe.

Les états ne remplacent pas le ledger par module/version. Ils servent de vue rapide et de filtre de scheduling.

Décodage contextualisé

Le décodeur ne doit pas être limité à CoreInstructionRow.payload_json.

Certains protocoles Solana exigent de lire :

  • les inner instructions ;
  • les logs Anchor ou non Anchor ;
  • les balances avant/après ;
  • les comptes résolus ;
  • les loaded addresses ;
  • les erreurs de transaction ;
  • des séquences de logs liées à un CPI ;
  • des instructions voisines de la même transaction.

MdCoreInstructionReplayInput représente ce contrat de lecture : une instruction ciblée plus un contexte extrait depuis les tables core. Depuis le contrat 2, ce contexte inclut également toutes les instructions outer de la signature, ordonnées numériquement et munies de leur payload retenu et de son hash.

Sélection de replay

CoreInstructionReplayFilter permet de sélectionner les instructions par :

  • état de traitement ;
  • program_id ;
  • plage de slots.

L'usage standard pour un worker de decode sera :

processing_state = Pending ou ReplayRequested
program_id = programme ciblé par le décodeur
plage de slots = optionnelle

Le repository charge les logs, balances, account keys et instructions outer nécessaires pour retourner MdCoreInstructionReplayInput. La liste outer inclut la cible et utilise les champs stables instructionIndex, instructionPath, programId, payloadJson et payloadHash. Cette extension lit les tables existantes et ne demande aucune migration.

Marquage de cycle de vie

CoreInstructionLifecycleMark permet à un module de changer l'état d'une instruction après traitement.

Exemples :

  • un décodeur reconnu marque l'instruction Decoded ;
  • un materializer complet marque l'instruction Materialized ;
  • un décodeur non concerné peut marquer Ignored dans un contexte contrôlé ;
  • une erreur de parsing marque Failed ;
  • une correction de décodeur peut remettre ReplayRequested.

Relation avec kb_sol_ops_processing_ledger

Le processing ledger garde le détail par module, version et input. L'état sur l'instruction reste le dernier état opérationnel visible.

Pour éviter les doublons, l'input key du ledger devra être stable, par exemple :

signature:instruction_path:program_id:processor_name:processor_version

La forme exacte n'est pas figée en 0.2.1, mais elle doit rester déterministe.

Rétention du payload d'instruction et des logs

Le payload JSON d'une instruction et le texte des logs sont utiles au début. Plus tard, après décodage et matérialisation fiables, ils pourront être compactés ou purgés avec conservation d'un hash.

Les entities CoreInstructionRow et CoreLogRow préparent ce cas en autorisant :

  • payload ou texte présent ;
  • payload ou texte absent ;
  • hash conservé ;
  • état de traitement consultable pour replay.

La purge effective ne doit pas être implémentée avant que les diagnostics de replay soient fiables.

Décision pour 0.2.1

0.2.1 ajoute les contrats Rust nécessaires, mais ne crée pas encore les tables SQL. Les migrations réelles restent prévues pour 0.2.3 et 0.2.4.