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
Ignoreddans 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.