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

# Armazenamento e provas

> Como o estado confirmado é persistido em três repositórios RocksDB, autenticado por uma árvore de Merkle versionada e por acumuladores, e podado ao longo do tempo.

O estado confirmado tem de satisfazer duas exigências que puxam em sentidos opostos. A execução quer o valor atual de uma chave, depressa, milhões de vezes. A verificação quer uma prova de que um valor era aquilo que a rede diz que era numa versão determinada. Servir ambas a partir de uma só estrutura significa fazer as duas mal.

O armazenamento reparte, por isso, o problema por repositórios separados, cada um moldado ao seu próprio padrão de acesso.

<h2 id="three-stores">
  Três repositórios
</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">Bloco confirmado</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">Repositório do ledger</span><span className="dg-s">transações · resultados · eventos · escritas · acumuladores · metadados</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">Reexecução e auditoria</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">Repositório KV de estado</span><span className="dg-s">valores atuais e históricos, repartidos por 16 shards, estado quente em nível próprio</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">Consultas e execução</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">Repositório Merkle de estado</span><span className="dg-s">árvore de Merkle esparsa versionada, mais os índices dos nós substituídos</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">Verificação — provas</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"89.1566%",width:"100.0000%"}}><div className="dg-n">Uma leitura que só precisa de um valor não paga o percurso da árvore, e uma prova não se reconstrói de um repositório otimizado para pesquisas pontuais.</div></div>
  </div>
</div>

O **repositório do ledger** guarda o histórico da cadeia: transações, os seus resultados e dados auxiliares, eventos, conjuntos de escrita, metadados de bloco e os acumuladores. É isto que se reexecuta.

O **repositório KV de estado** guarda os valores de estado, endereçados por chave e por versão. É o que a execução e as consultas leem. Está **repartido por dezasseis shards**, para que as escritas de um bloco se distribuam por dezasseis instâncias RocksDB independentes em vez de disputarem uma só. O estado acedido com frequência é ainda mantido num nível próprio, para que o conjunto de trabalho de um mercado ativo não tenha de ser encontrado no meio de tudo o que a cadeia alguma vez guardou.

O **repositório Merkle de estado** guarda a estrutura autenticada — os nós da árvore que permitem provar um valor e os índices que registam que nós foram substituídos.

Separá-los significa que uma leitura que só precisa de um valor não paga o percurso da árvore, e que uma prova não tem de ser reconstruída a partir de um repositório otimizado para pesquisas pontuais.

<h2 id="authentication">
  Autenticação
</h2>

Duas estruturas de Merkle fazem trabalhos diferentes.

<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">Árvore de Merkle esparsa versionada</span></div>
    <div className="dg-band" style={{left:"51.8056%",top:"6.5000%",width:"48.1944%",height:"72.5000%"}}><span className="dg-cap">Acumuladores</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">A chave e o seu valor</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"30.1250%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">hash irmão</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"47.7500%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">hash irmão</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">Raiz do estado, confirmada pelo consenso</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">Uma transação, ou um evento</span></div>
    <div className="dg-b" style={{left:"54.0278%",top:"36.0000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Acumulador de transações · de eventos</span><span className="dg-s">cada um fixa, por ordem, tudo o que foi incluído</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">Raiz do ledger, confirmada pelo consenso</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">A árvore prova qual era um valor; os acumuladores provam o que aconteceu e por que ordem. Juntos, tornam demonstrável «esta transação está na cadeia nesta posição» sem guardar a cadeia.</span></div>
  </div>
</div>

Uma **árvore de Merkle esparsa versionada** autentica o estado. Cada chave tem uma posição determinada pelo seu hash, e cada versão da árvore partilha os nós que não mudaram — escrever uma chave num bloco acrescenta um caminho, não uma árvore. A prova de uma chave numa dada versão é o caminho da folha dessa chave até à raiz que a rede confirmou.

Os **acumuladores** autenticam a sequência. Um acumula transações e outro acumula eventos, produzindo cada um uma raiz que fixa, por ordem, tudo o que foi incluído até ao momento. É isto que torna demonstrável a afirmação «esta transação está na cadeia nesta posição» sem ter de guardar a cadeia.

Entre as duas: a árvore de estado prova *qual era um valor*, os acumuladores provam *o que aconteceu e por que ordem*.

<h3 id="speculative-state">
  Estado especulativo
</h3>

Os resultados de um bloco existem antes de serem confirmados. Em vez de os escrever na árvore durável e desfazer essa escrita caso o bloco não seja confirmado, o estado por confirmar é mantido numa **camada esparsa de Merkle em memória**, sobreposta à última versão confirmada.

A execução lê através dessa camada e vê uma visão consistente. Se o bloco for confirmado, a camada é materializada. Se não for, a camada é descartada e nada de durável chegou a ser tocado. É isto que impede a execução especulativa de deixar detritos no armazenamento.

<h3 id="caching">
  Cache
</h3>

Os nós da árvore são mantidos em cache a dois níveis: uma cache consciente das versões, que mantém as versões recentes endereçáveis, e, por baixo dela, uma cache de substituição LRU (menos recentemente usado). O padrão de acesso de uma cadeia de negociação — um pequeno conjunto de chaves quentes tocadas em cada bloco, contra uma cauda longa raramente tocada — é exatamente o padrão para que estas caches existem.

<h2 id="pruning">
  Poda
</h2>

Guardar todas as versões para sempre é uma escolha, não um requisito. Três podadores independentes correm sobre os três repositórios, cada um com a sua política de retenção: um sobre o ledger, um sobre os valores de estado, um sobre os nós de Merkle.

Os podadores de Merkle e de valores de estado são guiados por **índices de obsolescência** escritos ao mesmo tempo que os dados. Quando uma versão substitui um nó ou um valor, a entrada substituída é registada como obsoleta nessa versão. A poda passa então a ser um varrimento de um intervalo de um índice, e não uma busca por lixo — quem escreveu já disse o que ficaria recolhível e a partir de quando.

<Note>
  A retenção é uma decisão do operador com consequências reais. Um nó podado de forma agressiva serve o estado atual com eficiência e não consegue responder a consultas históricas nem servir a sincronização de estado a um nó que arranque de mais atrás. Um nó de arquivo guarda tudo e paga por isso. Ver [Operar um nó](/pt/developers/run-a-node).
</Note>

<h2 id="backup-and-restore">
  Cópias de segurança e reposição
</h2>

Os repositórios podem ser copiados e repostos independentemente do nó em execução, e é isso que torna possível levantar um nó a partir de um snapshot em vez de reexecutar desde a génese, e verificar o estado de um nó reposto contra as raízes confirmadas em vez de confiar na cópia de segurança.

<h2 id="where-to-go-next">
  Para onde ir a seguir
</h2>

<CardGroup cols={2}>
  <Card title="Sincronização de estado" href="/pt/protocol/architecture/state/sync">
    Como um nó alcança a cadeia sem reexecutar tudo.
  </Card>

  <Card title="Modelo de estado" href="/pt/protocol/architecture/state/model">
    O que está a ser guardado e qual a representação que tem autoridade.
  </Card>

  <Card title="Indexador" href="/pt/protocol/architecture/indexer">
    Reconstruir o histórico a partir dos registos confirmados.
  </Card>

  <Card title="Operar um nó" href="/pt/developers/run-a-node">
    Os papéis de nó e como pedir informações sobre operar um.
  </Card>
</CardGroup>
