> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Stockage et preuves

> Comment l’état entériné est persisté dans trois magasins RocksDB, authentifié par un arbre de Merkle versionné et des accumulateurs, puis élagué au fil du temps.

L’état entériné doit satisfaire deux exigences qui tirent en sens contraire. L’exécution veut la valeur courante d’une clé, vite, des millions de fois. La vérification veut une preuve qu’une valeur était bien celle que le réseau annonce, à une version donnée. Servir les deux depuis une seule structure revient à mal faire les deux.

Le stockage découpe donc le problème entre des magasins distincts, chacun taillé pour son propre schéma d’accès.

<h2 id="three-stores">
  Trois magasins
</h2>

<div className="dg" data-dg="storage-stores">
  <div className="dg-c" style={{aspectRatio:"720 / 332"}}>
    <svg className="dg-w" viewBox="0 0 720 332" aria-hidden="true">
      <path className="dg-wire dg--green dg-dash" d="M 434.00 48.00 L 459.60 48.00" />

      <path className="dg-head dg--green" d="M 466.00 48.00 L 459.60 52.40 L 459.60 43.60 Z" />

      <path className="dg-wire dg--green dg-dash" d="M 434.00 144.00 L 459.60 144.00" />

      <path className="dg-head dg--green" d="M 466.00 144.00 L 459.60 148.40 L 459.60 139.60 Z" />

      <path className="dg-wire dg--green dg-dash" d="M 434.00 240.00 L 459.60 240.00" />

      <path className="dg-head dg--green" d="M 466.00 240.00 L 459.60 244.40 L 459.60 235.60 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 135.00 144.00 L 172.54 53.91" />

      <path className="dg-head dg--blue" d="M 175.00 48.00 L 176.60 55.60 L 168.48 52.22 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 135.00 144.00 L 168.60 144.00" />

      <path className="dg-head dg--blue" d="M 175.00 144.00 L 168.60 148.40 L 168.60 139.60 Z" />

      <path className="dg-wire dg--blue dg-soft" d="M 135.00 144.00 L 172.54 234.09" />

      <path className="dg-head dg--blue" d="M 175.00 240.00 L 168.48 235.78 L 176.60 232.40 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"31.3253%",width:"18.0556%",height:"24.0964%"}}><span className="dg-t">Bloc entériné</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"25.0000%",top:"2.4096%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Magasin du registre</span><span className="dg-s">transactions · sorties · événements · écritures · accumulateurs · métadonnées</span></div>
    <div className="dg-b dg--green" style={{left:"65.2778%",top:"2.4096%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Rejeu et audit</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"25.0000%",top:"31.3253%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Magasin KV d’état</span><span className="dg-s">valeurs courantes et historiques, seize partitions, état chaud à part</span></div>
    <div className="dg-b dg--green" style={{left:"65.2778%",top:"31.3253%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Requêtes et exécution</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"25.0000%",top:"60.2410%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Magasin Merkle d’état</span><span className="dg-s">un arbre de Merkle creux versionné, plus les index des nœuds remplacés</span></div>
    <div className="dg-b dg--green" style={{left:"65.2778%",top:"60.2410%",width:"34.7222%",height:"24.0964%"}}><span className="dg-t">Vérification — preuves</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"89.1566%",width:"100.0000%"}}><div className="dg-n">Une lecture qui ne veut qu’une valeur ne paie pas le parcours d’un arbre, et une preuve ne vient pas d’un magasin optimisé pour les accès ponctuels.</div></div>
  </div>
</div>

**Le magasin du registre** contient l’historique de la chaîne : les transactions, leurs sorties et données auxiliaires, les événements, les ensembles d’écritures, les métadonnées de bloc et les accumulateurs. C’est ce que l’on rejoue.

**Le magasin KV d’état** contient les valeurs d’état, adressées par clé et par version. C’est ce que lisent l’exécution et les requêtes. Il est **partitionné en seize**, de sorte que les écritures d’un même bloc se répartissent sur seize instances RocksDB indépendantes au lieu d’entrer en contention sur une seule. L’état fréquemment consulté est en outre conservé dans son propre palier, pour que l’ensemble de travail d’un marché actif n’ait pas à être trouvé au milieu de tout ce que la chaîne a jamais stocké.

**Le magasin Merkle d’état** contient la structure authentifiée — les nœuds de l’arbre qui permettent de prouver une valeur, et les index qui suivent quels nœuds ont été remplacés.

Les séparer signifie qu’une lecture qui n’a besoin que d’une valeur ne paie pas le parcours d’un arbre, et qu’une preuve n’a pas à être reconstruite depuis un magasin optimisé pour les accès ponctuels.

<h2 id="authentication">
  Authentification
</h2>

Deux structures de Merkle font des travaux différents.

<div className="dg" data-dg="storage-proofs">
  <div className="dg-c" style={{aspectRatio:"720 / 400"}}>
    <svg className="dg-w" viewBox="0 0 720 400" aria-hidden="true">
      <path className="dg-wire" d="M 173.50 98.50 L 173.50 110.10" />

      <path className="dg-head" d="M 173.50 116.50 L 169.10 110.10 L 177.90 110.10 Z" />

      <path className="dg-wire" d="M 173.50 169.00 L 173.50 180.60" />

      <path className="dg-head" d="M 173.50 187.00 L 169.10 180.60 L 177.90 180.60 Z" />

      <path className="dg-wire" d="M 173.50 239.50 L 173.50 251.10" />

      <path className="dg-head" d="M 173.50 257.50 L 169.10 251.10 L 177.90 251.10 Z" />

      <path className="dg-wire" d="M 546.50 122.00 L 546.50 133.60" />

      <path className="dg-head" d="M 546.50 140.00 L 542.10 133.60 L 550.90 133.60 Z" />

      <path className="dg-wire" d="M 546.50 216.00 L 546.50 227.60" />

      <path className="dg-head" d="M 546.50 234.00 L 542.10 227.60 L 550.90 227.60 Z" />
    </svg>

    <div className="dg-band" style={{left:"0.0000%",top:"6.5000%",width:"48.1944%",height:"72.5000%"}}><span className="dg-cap">Arbre de Merkle creux versionné</span></div>
    <div className="dg-band" style={{left:"51.8056%",top:"6.5000%",width:"48.1944%",height:"72.5000%"}}><span className="dg-cap">Accumulateurs</span></div>
    <div className="dg-b dg--blue" style={{left:"2.2222%",top:"12.5000%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">Votre clé et sa valeur</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"30.1250%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">hash frère</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"47.7500%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">hash frère</span></div>
    <div className="dg-b dg--green" style={{left:"2.2222%",top:"65.3750%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">Racine d’état, entérinée par consensus</span></div>
    <div className="dg-b dg--blue" style={{left:"54.0278%",top:"12.5000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Votre transaction ou un événement</span></div>
    <div className="dg-b" style={{left:"54.0278%",top:"36.0000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Accumulateur de transactions · d’événements</span><span className="dg-s">chacun engage tout ce qui précède, dans l’ordre</span></div>
    <div className="dg-b dg--green" style={{left:"54.0278%",top:"59.5000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Racine du registre entérinée</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"83.0000%",width:"100.0000%",height:"14.5000%"}}><span className="dg-s">L’arbre prouve ce qu’une valeur était ; les accumulateurs, ce qui s’est passé et dans quel ordre. Ensemble ils rendent prouvable « cette transaction est dans la chaîne à cette position » sans détenir la chaîne.</span></div>
  </div>
</div>

**Un arbre de Merkle creux versionné** authentifie l’état. Chaque clé a une position déterminée par son hash, et chaque version de l’arbre partage les nœuds qui n’ont pas changé — écrire une clé dans un bloc ajoute donc un chemin, pas un arbre. La preuve d’une clé à une version donnée est le chemin qui va de la feuille de cette clé jusqu’à la racine que le réseau a entérinée.

**Les accumulateurs** authentifient la séquence. L’un accumule les transactions, l’autre les événements, chacun produisant une racine qui engage tout ce qui a été inclus jusque-là, dans l’ordre. C’est ce qui rend prouvable, sans détenir la chaîne, l’affirmation « cette transaction est dans la chaîne à cette position ».

À eux deux : l’arbre d’état prouve *quelle était une valeur*, les accumulateurs prouvent *ce qui s’est passé et dans quel ordre*.

<h3 id="speculative-state">
  État spéculatif
</h3>

Les résultats d’un bloc existent avant d’être entérinés. Plutôt que de les écrire dans l’arbre durable puis de défaire cette écriture si le bloc n’est pas entériné, l’état non entériné est maintenu dans une **surcouche de Merkle creuse en mémoire**, posée sur la dernière version entérinée.

L’exécution lit à travers la surcouche et voit une vue cohérente. Si le bloc est entériné, la surcouche est matérialisée. Sinon, elle est abandonnée et rien de durable n’a jamais été touché. C’est ce qui empêche l’exécution spéculative de laisser des résidus dans le stockage.

<h3 id="caching">
  Mise en cache
</h3>

Les nœuds de l’arbre sont mis en cache à deux niveaux : un cache conscient des versions, qui garde les versions récentes adressables, et sous lui un cache par éviction du moins récemment utilisé. Le schéma d’accès d’une chaîne de trading — un petit ensemble de clés chaudes touchées à chaque bloc, face à une longue traîne rarement touchée — est exactement la forme à laquelle ces caches répondent.

<h2 id="pruning">
  Élagage
</h2>

Conserver toutes les versions à jamais est un choix, pas une obligation. Trois élagueurs indépendants travaillent sur les trois magasins, chacun avec sa propre politique de rétention : un sur le registre, un sur les valeurs d’état, un sur les nœuds de Merkle.

Les élagueurs Merkle et de valeurs d’état sont pilotés par des **index de péremption** écrits en même temps que les données. Quand une version remplace un nœud ou une valeur, l’entrée remplacée est enregistrée comme périmée à cette version. L’élagage devient alors un parcours de plage sur un index plutôt qu’une recherche de déchets — celui qui écrit a déjà dit ce qui deviendrait collectable, et quand.

<Note>
  La rétention est une décision d’opérateur qui a de vraies conséquences. Un nœud élagué agressivement sert efficacement l’état courant et ne peut ni répondre aux requêtes historiques, ni fournir la synchronisation d’état à un nœud qui démarre de plus loin. Un nœud d’archive garde tout, et le paie. Voir [Faire tourner un nœud](/fr/developers/run-a-node).
</Note>

<h2 id="backup-and-restore">
  Sauvegarde et restauration
</h2>

Les magasins peuvent être sauvegardés et restaurés indépendamment du nœud en fonctionnement, ce qui permet de monter un nœud à partir d’un instantané plutôt que de rejouer depuis la genèse, et de vérifier l’état d’un nœud restauré contre les racines entérinées plutôt que de faire confiance à la sauvegarde.

<h2 id="where-to-go-next">
  Pour aller plus loin
</h2>

<CardGroup cols={2}>
  <Card title="Synchronisation d’état" href="/fr/protocol/architecture/state/sync">
    Comment un nœud rattrape la chaîne sans la rejouer en entier.
  </Card>

  <Card title="Modèle d’état" href="/fr/protocol/architecture/state/model">
    Ce qui est stocké, et quelle représentation fait autorité.
  </Card>

  <Card title="Indexeur" href="/fr/protocol/architecture/indexer">
    Reconstruire l’historique à partir des enregistrements entérinés.
  </Card>

  <Card title="Faire tourner un nœud" href="/fr/developers/run-a-node">
    Les rôles de nœud, et comment demander à en opérer un.
  </Card>
</CardGroup>
