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

# Penyimpanan dan bukti

> Bagaimana state yang terkomit dipertahankan di tiga store RocksDB, diautentikasi oleh pohon Merkle berversi dan akumulator, lalu di-prune seiring waktu.

State yang terkomit harus memenuhi dua tuntutan yang saling tarik-menarik. Eksekusi menginginkan nilai terkini sebuah key, dengan cepat, jutaan kali. Verifikasi menginginkan bukti bahwa nilai sebuah key memang seperti yang dinyatakan jaringan pada versi tertentu. Melayani keduanya dari satu struktur berarti melakukan keduanya dengan buruk.

Karena itu lapisan penyimpanan memecah masalah ini ke beberapa store terpisah, masing-masing dibentuk untuk pola aksesnya sendiri.

<h2 id="three-stores">
  Tiga store
</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">Blok terkomit</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">Ledger store</span><span className="dg-s">transaksi · output · event · write set · akumulator · metadata blok</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">Replay dan 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">State KV store</span><span className="dg-s">nilai kini dan historis, 16 shard, state panas di tier tersendiri</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">Query dan eksekusi</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">State Merkle store</span><span className="dg-s">sparse Merkle tree berversi, plus indeks node yang digantikan</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">Verifikasi — bukti</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"89.1566%",width:"100.0000%"}}><div className="dg-n">Pembacaan yang hanya butuh nilai tidak membayar penelusuran pohon, dan bukti tidak direkonstruksi dari store yang dioptimalkan untuk point lookup.</div></div>
  </div>
</div>

**Ledger store** menyimpan riwayat chain: transaksi, output dan data pendukungnya, event, write set, metadata blok, dan akumulator. Inilah yang Anda replay.

**State KV store** menyimpan nilai state, dialamatkan berdasarkan key dan versi. Inilah yang dibaca eksekusi dan query. Store ini **di-shard menjadi enam belas bagian**, sehingga penulisan dari satu blok tersebar ke enam belas instance RocksDB independen alih-alih berebut pada satu instance. State yang sering diakses juga disimpan di tier tersendiri, sehingga working set pasar aktif tidak perlu dicari di antara segala hal yang pernah disimpan chain.

**State Merkle store** menyimpan struktur terautentikasi — node pohon yang membuat nilai bisa dibuktikan, dan indeks yang melacak node mana yang sudah digantikan.

Memisahkan ketiganya berarti pembacaan yang hanya butuh nilai tidak perlu membayar biaya penelusuran pohon, dan bukti tidak perlu direkonstruksi dari store yang dioptimalkan untuk point lookup.

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

Dua struktur Merkle mengerjakan tugas yang berbeda.

<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">Sparse Merkle tree berversi</span></div>
    <div className="dg-band" style={{left:"51.8056%",top:"6.5000%",width:"48.1944%",height:"72.5000%"}}><span className="dg-cap">Akumulator</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">Key Anda dan nilainya</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"30.1250%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">hash sibling</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"47.7500%",width:"43.7500%",height:"11.1250%"}}><span className="dg-t">hash sibling</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">State root, dikomit konsensus</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">Transaksi Anda, atau event</span></div>
    <div className="dg-b" style={{left:"54.0278%",top:"36.0000%",width:"43.7500%",height:"17.0000%"}}><span className="dg-t">Akumulator transaksi · akumulator event</span><span className="dg-s">masing-masing mengikat semua yang masuk, berurutan</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">Ledger root, dikomit konsensus</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">Pohon membuktikan berapa nilai sebuah key; akumulator membuktikan apa yang terjadi dan urutannya. Bersama-sama keduanya membuat “transaksi ini ada di chain pada posisi ini” bisa dibuktikan tanpa menyimpan chain.</span></div>
  </div>
</div>

**Sparse Merkle tree berversi** mengautentikasi state. Setiap key punya posisi yang ditentukan oleh hash-nya, dan setiap versi pohon berbagi node yang tidak berubah — jadi menulis satu key di dalam blok menambahkan satu jalur, bukan satu pohon. Bukti untuk sebuah key pada versi tertentu adalah jalur dari daun key itu ke root yang dikomit jaringan.

**Akumulator** mengautentikasi urutan. Satu akumulator mengumpulkan transaksi dan satu lagi mengumpulkan event, masing-masing menghasilkan root yang mengikat semua yang sudah masuk sejauh ini beserta urutannya. Inilah yang membuat “transaksi ini ada di chain pada posisi ini” bisa dibuktikan tanpa menyimpan seluruh chain.

Di antara keduanya: pohon state membuktikan *berapa nilai sebuah key saat itu*, akumulator membuktikan *apa yang terjadi dan dalam urutan apa*.

<h3 id="speculative-state">
  State spekulatif
</h3>

Hasil sebuah blok sudah ada sebelum blok itu dikomit. Alih-alih menulisnya ke pohon durabel lalu membatalkannya jika blok itu tidak jadi dikomit, state yang belum terkomit ditahan di dalam **overlay sparse Merkle in-memory** di atas versi terakhir yang terkomit.

Eksekusi membaca menembus overlay itu dan melihat tampilan yang konsisten. Jika blok terkomit, overlay dimaterialisasi. Jika tidak, overlay dibuang dan tidak ada apa pun yang durabel pernah tersentuh. Inilah yang menjaga eksekusi spekulatif agar tidak meninggalkan sampah di penyimpanan.

### Caching

Node pohon di-cache pada dua tingkat: cache yang sadar versi sehingga versi-versi terbaru tetap bisa dialamatkan, dan di bawahnya cache least-recently-used. Pola akses chain trading — sekumpulan kecil key panas yang tersentuh setiap blok, berhadapan dengan ekor panjang yang jarang tersentuh — persis bentuk yang menjadi alasan keduanya ada.

## Pruning

Menyimpan setiap versi selamanya adalah pilihan, bukan keharusan. Tiga pruner independen berjalan terhadap ketiga store, masing-masing dengan kebijakan retensinya sendiri: satu untuk ledger, satu untuk nilai state, satu untuk node Merkle.

Pruner Merkle dan pruner nilai state digerakkan oleh **indeks stale** yang ditulis bersamaan dengan datanya. Ketika satu versi menggantikan node atau nilai, entri yang digantikan itu dicatat sebagai stale pada versi tersebut. Dengan begitu pruning menjadi range scan atas indeks, bukan pencarian sampah — penulisnya sudah menyatakan apa yang akan bisa dibuang dan kapan.

<Note>
  Retensi adalah keputusan operator dengan konsekuensi nyata. Node yang di-prune secara agresif melayani state terkini dengan efisien tetapi tidak bisa menjawab query historis atau melayani sinkronisasi state untuk node yang mulai dari titik yang jauh di belakang. Node arsip menyimpan segalanya dan membayar harganya. Lihat [Menjalankan node](/id/developers/run-a-node).
</Note>

<h2 id="backup-and-restore">
  Backup dan restore
</h2>

Store dapat di-backup dan di-restore secara independen dari node yang sedang berjalan, dan itulah yang memungkinkan node dibangun dari snapshot alih-alih me-replay dari genesis, sekaligus memverifikasi state node hasil restore terhadap root yang terkomit alih-alih memercayai backup-nya.

<h2 id="where-to-go-next">
  Ke mana selanjutnya
</h2>

<CardGroup cols={2}>
  <Card title="Sinkronisasi state" href="/id/protocol/architecture/state/sync">
    Bagaimana node menyusul chain tanpa harus me-replay seluruhnya.
  </Card>

  <Card title="Model state" href="/id/protocol/architecture/state/model">
    Apa yang disimpan, dan representasi mana yang otoritatif.
  </Card>

  <Card title="Indexer" href="/id/protocol/architecture/indexer">
    Merekonstruksi riwayat dari catatan yang terkomit.
  </Card>

  <Card title="Menjalankan node" href="/id/developers/run-a-node">
    Peran node, dan cara menanyakan soal menjalankannya.
  </Card>
</CardGroup>
