Skip to main content
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.

Tiga store

Blok terkomit
Ledger storetransaksi · output · event · write set · akumulator · metadata blok
Replay dan audit
State KV storenilai kini dan historis, 16 shard, state panas di tier tersendiri
Query dan eksekusi
State Merkle storesparse Merkle tree berversi, plus indeks node yang digantikan
Verifikasi — bukti
Pembacaan yang hanya butuh nilai tidak membayar penelusuran pohon, dan bukti tidak direkonstruksi dari store yang dioptimalkan untuk point lookup.
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.

Autentikasi

Dua struktur Merkle mengerjakan tugas yang berbeda.
Sparse Merkle tree berversi
Akumulator
Key Anda dan nilainya
hash sibling
hash sibling
State root, dikomit konsensus
Transaksi Anda, atau event
Akumulator transaksi · akumulator eventmasing-masing mengikat semua yang masuk, berurutan
Ledger root, dikomit konsensus
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.
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.

State spekulatif

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

Backup dan restore

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.

Ke mana selanjutnya

Sinkronisasi state

Bagaimana node menyusul chain tanpa harus me-replay seluruhnya.

Model state

Apa yang disimpan, dan representasi mana yang otoritatif.

Indexer

Merekonstruksi riwayat dari catatan yang terkomit.

Menjalankan node

Peran node, dan cara menanyakan soal menjalankannya.