Rand Protocol
Dokumentasi
Konsep teras

Konsensus dan kemuktamadan

Chained HotStuff seperti yang dijalankan oleh nod - kuorum, pemimpin, peraturan komit tiga pandangan berturut-turut, tamat masa, epok - dan maksud "muktamad" bagi sebuah klien pada testnet.

Gunakan halaman ini untuk mengetahui bila sesuatu transaksi dimuktamadkan, berapa banyak validator yang mesti berfungsi, dan apakah maksud medan blok yang anda lihat dalam RPC dan penjelajah. Konsensus ialah HotStuff BFT berantai dengan kuorum berpemberat pertaruhan; pada chain 20 itu ialah 18 daripada 26 validator.

Peraturan yang dijalankan nod

peraturanpelaksanaan
Kuorumsijil kuorum (QC) ialah set undi Dilithium2 daripada validator yang memegang lebih daripada 2/3 secara ketat jumlah pertaruhan
Jadual pemimpinpusingan bergilir (round robin) semata-mata: pemimpin bagi view v ialah validators[v mod n], dengan set disusun mengikut alamat. Pertaruhan memberi pemberat kepada undi, bukan pemilihan pemimpin
Pencadanganpemimpin bagi view v mengemukakan cadangan sebaik sahaja ia memegang QC untuk v − 1, atau kuorum mesej NewView untuk v. Cadangan yang akan menerapkan transaksi tidak sah menggugurkan transaksi itu, bukan blok tersebut
Pengundian dan keselamatanseorang validator mengundi sekali setiap view, dan hanya untuk blok yang selamat berhubung kunci (lock) miliknya (QC justify blok itu lebih baharu daripada QC yang dikunci, atau blok itu menyambung blok yang dikunci). Keadaan keselamatan di-fsync ke RocksDB sebelum sesuatu undi meninggalkan nod
Domain tandatanganpada genesis dengan consensus_domain: 1 (chain 20, dan setiap chain sejak 15) setiap tandatangan undi, new-view dan cadangan merangkumi hash genesis (rand-vote-2, rand-newview-2, rand-block-2), maka tandatangan untuk satu chain tidak disahkan pada mana-mana chain lain. Chain 14 dan sebelumnya menandatangani tanpanya. binding_domain: 1 pada chain 20 melanjutkan peraturan yang sama kepada bukti transaksi dan tindakan bertandatangan (Transaksi)
Cadangan adik-beradiksesebuah replika memegang satu blok bagi setiap (view, pemimpin); blok kedua yang berbeza daripada pemimpin itu untuk view itu ditolak sebagai equivocation. Cadangan yang melebihi 8 view daripada view replika itu sendiri (PROPOSAL_VIEW_WINDOW) ditolak sebelum tandatangannya diperiksa; pokok spekulatif yang penuh akan menyingkirkan blok luar cabang sebelum menolak apa-apa
Pelepasan kuncikunci tidak pernah diturunkan secara automatik (CON-4, v0.6.8). Ia hanya tunduk kepada cadangan yang QC justify-nya mengatasinya, atau kepada ketibaan blok yang dikunci. Kuorum jawapan NotHeld bertandatangan dilog untuk operator dan tidak melepaskan apa-apa, dan seorang validator merekodkan undinya supaya ia tidak sekali-kali menandatangani NotHeld untuk blok yang telah diundinya. Setiap blok yang disahkan di atas head disimpan dan dipulihkan semasa mula semula, supaya mula semula seluruh armada tidak meninggalkan QC pada blok yang tiada sesiapa pegang. Validator yang blok terkuncinya hilang selama-lamanya dilepaskan secara manual, di luar talian: rand-node safety release-lock
Pemasangan QCsetiap validator memasang QC secara setempat daripada undi yang digosipkan, maka chain terus membuat commit walaupun pemimpin berikutnya di luar talian
Commitperaturan tiga-QC berantai: sesebuah blok di-commit sebaik sahaja tiga sijil berantai di atasnya dalam view berturutan v, v+1, v+2 dan rantaian itu bersambung kembali kepada head yang telah di-commit
Tamat masa dan pertukaran viewasas --view-timeout-ms 3,000 ms, berganda bagi setiap tamat masa berturutan, ditetapkan semula apabila ada kemajuan. Pacemaker sijil tamat masa (CH-1, v0.6.8): replika yang pemasanya berbunyi kekal dalam view-nya dan menandatangani NewView yang meminta view seterusnya. Ia memasuki sesuatu view apabila ada QC untuk view sebelumnya, atau apabila validator yang memegang lebih daripada 2/3 pertaruhan telah meminta view itu atau view yang lebih kemudian; ia menyertai (menandatangani permintaannya sendiri) apabila lebih daripada 1/3 meminta view yang melebihi view miliknya. NewView daripada seorang validator sahaja tidak menggerakkan sesiapa. View dihadkan (MAX_VIEW_AHEAD = 10⁶)
Kadarpemimpin mencadangkan blok kosong apabila tiada apa-apa yang menunggu, sekurang-kurangnya --block-interval-ms (lalai 1,000 ms) selepas blok terakhir yang dilihat daripada mana-mana pencadang
Had undi dan gosipundi yang melebihi 8 view ke hadapan diabaikan dan satu undi dikira bagi setiap (view, pengundi); gosip konsensus diukur bagi setiap rakan pemaju (burst 256, 64/s); cadangan yang induknya tidak diketahui disimpan sebagai yatim hanya jika pencadangnya memimpin view tersebut dalam set epoch semasa atau set epoch seterusnya, ia berada dalam had pokok daripada head yang telah di-commit, dan saiz serta tx root-nya sah (kolam yatim dihadkan pada 64 MiB, dan sejak v0.6.1 pada 16 yatim bagi setiap pencadang). Sejak v0.6.8 sesuatu cadangan dipajukan, dan yatim disimpan, hanya jika senarai transaksinya di-hash kepada root yang diikat oleh pengepalanya tanpa sebarang transaksi berulang (GOSSIP-2)
Had blokmax_block_bytes chain itu bagi bait transaksi (4 MiB secara lalai, 20 MiB dalam genesis chain 20) dan 2,000 transaksi, dikuatkuasakan oleh pencadang dan sekali lagi oleh setiap replika dalam Ledger::apply_block
Masa blokpada chain yang mempunyai seksyen bridge: timestamp_ms sesebuah blok tidak boleh mendahului induknya (TimestampRewind) dan tidak boleh melebihinya lebih daripada 60 s (TimestampLeap), dan seorang validator menahan undinya daripada blok yang lebih daripada 15 s di hadapan jamnya sendiri; lihat di bawah

Peraturan commit tiga-view berturutan itu menanggung beban: melonggarkannya membuka semula pepijat kemuktamadan yang bercanggah, yang mana fullnode mempunyai ujian regresi. Segala yang dilihat klien melalui RPC telah di-commit: hanya blok yang telah di-commit disajikan, dan strim WebSocket newHeads menghantar satu pemberitahuan bagi setiap blok yang di-commit, mengikut urutan.

Jadual ini ialah v0.6.8, keluaran yang dijalankan chain 20. Tiga daripada peraturannya baharu dalam v0.6.8 (audit v6) dan aktif sejak chain 20 beroperasi pada 2026-10-01: pacemaker sijil tamat masa (CH-1), tiada pelepasan kunci automatik (CON-4) dan semakan senarai transaksi cadangan (GOSSIP-2). Pada chain 18 dan 19 (v0.6.7), NewView bertandatangan daripada seorang validator sahaja menggerakkan setiap replika ke view-nya, dan kunci diturunkan atas jawapan NotHeld bertandatangan daripada kuorum pertaruhan. Pacemaker dan peraturan kunci mengubah apa yang ditandatangani validator dan bila, maka v0.6.8 dilancarkan dengan henti-semua/mula-semua bersama pemotongan chain 20, tidak sekali-kali nod demi nod.

Angka testnet

Chain 20 mempunyai 26 validator, masing-masing dipertaruhkan tepat 1,000 RAND, kesemua 26 berada dalam genesisnya pada kunci dan id rakan yang dijalankan chain 17 hingga 19. Pada chain 15 lapan belas berada dalam genesis, pada kunci chain 14, dan lapan lagi diikat pada 2026-09-27 di bawah pendaftaran v2 dan aktif dari epoch 43. Pertaruhan seragam, maka kuorum ialah kiraan kepala: 18 daripada 26 mesti dalam talian untuk membuat commit apa-apa. Dengan 17 aktif, view terus maju dan tiada apa-apa dimuktamadkan. Satu set n validator yang sama rata memerlukan lebih daripada 2/3 pertaruhan: 2 daripada 2, 3 daripada 4, 5 daripada 6, 13 daripada 18, 18 daripada 26. Had pemberat genesis (3,333 bps bagi setiap validator) tidak mengikat set pertaruhan yang sama rata.

Blok dikadarkan pada lalai 1,000 ms. Pada chain 15 ia tiba kira-kira setiap 1.2 s dalam amalan (purata 1.18 s sepanjang 29 jam pertamanya); pada chain 20 penjelajah melaporkan purata 1.34 s pada ketinggian 3,270 (2026-10-01, avg_block_time_ms). Penjelajah melaporkan purata masa blok yang diperhatikannya (avg_block_time_ms dalam GET /stats). View sesebuah validator mendahului ketinggian setiap kali view tamat masa, itulah sebabnya rand_getHead melaporkan kedua-duanya.

Epoch

Set validator diterbitkan semula daripada daftar setiap epoch_blocks = 1,000 blok (parameter genesis). epoch(h) = h / 1000; set bagi epoch e ≥ 1 diterbitkan daripada daftar pada blok terakhir epoch e − 1: setiap baris dengan stake ≥ 1,000 RAND, 100 teratas mengikut pertaruhan, disusun mengikut alamat. Pada chain tanpa seksyen staking, ikatan menjadi pemberat pada sempadan seterusnya. Pada chain 20 ia menunggu dua epoch lagi dan belanjawan kemasukan setiap epoch sebanyak 2,500 bps daripada pemberat terikat aktif pada sempadan (6,500 RAND apabila set memegang 26,000), dan ikatan yang mendaftarkan validator baharu ditolak kecuali set itu terlebih dahulu mengundi kunci tersebut masuk dengan AdmitValidator (staking.admission_by_vote). Belanjawan chain 19 ialah 10,000 RAND tetap setiap epoch, dan ia tiada undi kemasukan. Nyahikatan mengurangkan pemberat pada sempadan seterusnya, manakala jumlahnya menunggu dua epoch untuk boleh dikeluarkan. rand_getEpoch mengembalikan epoch, panjang epoch dan unjuran set seterusnya. Lihat Pertaruhan.

Apa yang dibawa sesebuah blok

{
  "hash": "647b…", "height": 50, "view": 92, "parent": "2d41…",
  "proposer": "3v3VBJ…", "timestamp_ms": 1788000123456,
  "tx_root": "0000…", "state_root": "a1b2…", "justify_view": 91,
  "tx_count": 0, "transactions": []
}

view ialah view tempat blok itu dicadangkan dan justify_view ialah view QC yang dibawanya untuk induknya. timestamp_ms ditetapkan oleh pencadang, dalam had seksyen berikutnya. state_root meng-commit lejar selepas blok itu. Pada chain 20:

inner      = blake3("rand-state-8" || tree_root || nullifier_root || validators_root || programs_root
                                   || bridge_root || tokens_root
                                   || faucet_epoch || faucet_minted_in_epoch || bond_queue_root
                                   || gas_price || byte_price
                                   || program_state_root)
state_root = blake3("rand-state-admitted-1" || inner || admitted_root)

Chain 19 meng-commit medan yang sama tanpa program_state_root, di bawah rand-state-7, tanpa pembungkus.

Komponen bergantung pada genesis. Rantaian tanpa sebarang bahagian pilihan mengikat empat komponen pertama di bawah rand-state-2. Bahagian bridge menambah bridge_root. Bahagian tokens menambah tokens_root selepasnya dan menukar domain seluruh cincangan kepada rand-state-4; genesis yang mempunyai bahagian bridge mesti mempunyai bahagian tokens, maka chain 20 mempunyai kedua-duanya. Bahagian aggregation menambah akar aggregator seterusnya (di bawah rand-state-3 pada rantaian tanpa token); chain 20 tidak mempunyainya. Bahagian staking menambah dua pembilang epoch faucet dan akar baris gilir bon (rand-bond-queue-1) pada penghujung, serta menukar domain seluruh cincangan kepada rand-state-5, walau apa pun yang lain dihidupkan; chain 14 tidak mempunyai bahagian sedemikian dan dicincang di bawah rand-state-4, manakala chain 15 hingga 17 dicincang di bawah rand-state-5. Bahagian vesting menambah akar daftar vesting selepas itu dan menukar domain cincangan kepada rand-state-6; chain 20 tidak mempunyainya. Bahagian gas dengan pengawal dynamic menambah gas_price dan byte_price semasa, masing-masing u64 big-endian, selepas semua yang lain dan menukar domain cincangan kepada rand-state-7. Itulah domain chain 19, dan chain 20 mengekalkan harga tersebut dalam akarnya: harga itu berubah sekali setiap blok, selepas transaksi blok itu dan sebelum akar (Fees). Bahagian gas dengan harga tetap tidak termasuk dalam akar. Bahagian program_state (RPL-2) menambah akar bagi semua sel dan peti simpanan setiap program selepas harga dan menukar domain cincangan kepada rand-state-8: domain chain 20. Keadaan staking Audit v6 dilipat di sekeliling domain itu dan bukan di dalamnya: di bawah staking.admission_by_vote (chain 20), akarnya ialah blake3("rand-state-admitted-1" || inner || admitted_root), dan di bawah staking.slashing (belum ada rantaian lagi), pembungkus kedua menambah set yang dipenjarakan. tokens_root ialah akar Merkle bagi daun blake3("rand-token-leaf-1" || bincode(TokenInfo)) mengikut urutan indeks, maka metadata, autoriti, mint_nonce, bekalan dan jumlah locked setiap sandaran bagi setiap token ialah keadaan konsensus: dua nod yang tidak sepakat tentang satu baris token tidak sepakat tentang rantaian. Pada chain 20, akar token turut melipat sambungan daftar (had max_tokens, yuran pendaftaran yang dibakar, had nilai note dan tetingkap had mint bergulir bagi bridge) di bawah rand-token-registry-3. Akar bridge meliputi pemancar, set penjaga, digest pengesahan yang telah dibelanjakan, jujukan pembakaran, kunci penjaga PQ, kunci jeda, bendera jeda dan dua nonce tadbir urus; daftar aset telah berpindah keluar daripadanya ke dalam tokens_root. Bridge chain 20 mempunyai rules_v2, maka nonce putaran dan parameter had global ditambah dan domainnya ialah rand-bridge-state-5 (domain chain 14 ialah rand-bridge-state-4); akar itu kemudian dibungkus oleh lantai ulang main masuk (rand-bridge-replay-floor-1), dan pada chain 20 juga oleh peraturan putaran dan putaran yang belum selesai (rand-bridge-rotation-1) serta kumpulan yuran (rand-bridge-fees-1). Daftar validator dicincang ke dalam validators_root (domain daun rand-validator-leaf-4 pada chain 20, dengan activation_epoch setiap baris; rand-validator-leaf-2 pada rantaian tanpa bahagian staking), maka nod yang tidak sepakat tentang satu baris daftar tidak sepakat tentang rantaian.

Masa blok dihadkan (B2)

Pada rantaian berjambatan, cap masa blok menentukan tamat tempoh set penjaga dan hari yang dikira bagi had mint harian sesuatu sandaran, maka seorang leader yang boleh melompatkan jam ke hadapan dapat menamatkan tempoh bertenang set yang diputarkan lebih awal atau melangkau had sesuatu hari. Chain 20 mempunyai bahagian bridge, maka tiga peraturan terpakai, kesemuanya bergantung padanya:

peraturanhadjenis
tiada pengundurantimestamp_ms ≥ parent.timestamp_ms (sama dibenarkan), jika tidak BlockError::TimestampRewind; proposer mengeluarkan max(now, parent.timestamp_ms)kesahihan, disemak semasa main semula dan penyegerakan juga
tiada lompatantimestamp_ms ≤ parent.timestamp_ms + MAX_TIMESTAMP_STEP_MS (60,000 ms), jika tidak BlockError::TimestampLeapkesahihan, disemak semasa main semula dan penyegerakan juga
sisihan jamvalidator enggan mengundi blok yang melebihi MAX_CLOCK_DRIFT_MS (15,000 ms) di hadapan jamnya sendiriperaturan undi sahaja: blok kekal dalam pokok spekulatif, kuorum yang jamnya sepakat masih boleh mensijilkannya, dan main semula sejarah yang telah dikomit tidak pernah menerapkannya

Setiap validator pada rantaian berjambatan memerlukan NTP. Validator yang jamnya tersasar lebih daripada 15 saat ialah leader yang cacat (cadangannya mungkin tidak mendapat undi) dan pengundi yang cacat (ia mungkin enggan mengundi blok tepat pada masanya daripada leader yang jujur). Kedua-duanya tidak menghentikan rantaian selagi jam majoriti yang jujur sepakat, tetapi armada yang tidak disegerakkan kehilangan margin liveness tanpa sebab.

timestamp_ms genesis mesti hampir dengan masa pelancaran sebenar. Jika terlalu jauh pada masa lalu, masa blok ketinggalan daripada jam dinding sehingga had langkah membenarkannya mengejar, paling banyak 60 s setiap blok. Jika lebih daripada 15 s pada masa hadapan, blok 1 langsung tidak dikomit: setiap undi, termasuk undi leader sendiri, ditahan sehingga masa dinding mencapainya. Selepas penghentian yang panjang, pengejaran yang sama boleh menggulirkan satu hari had mint lebih pantas daripada sekali setiap hari sebenar, dihadkan kepada had satu hari tambahan bagi setiap hari penuh ketinggalan terkumpul.

Kemuktamadan bagi klien

  • Transaksi muktamad apabila rand_getTransaction(hash) mengembalikan blok. Penerimaan oleh rand_sendTransaction hanyalah kemasukan ke dalam mempool.
  • Blok yang dihidangkan oleh RPC atau diindeks oleh explorer telah dikomit. Tiada tetingkap kemuktamadan untuk ditunggu; panduan explorer menyatakan perkara yang sama.
  • Kepala daripada rand_subscribe ["newHeads"] ialah kepala yang tidak akan hilang daripada nod: tiada apa dihantar sebelum blok dikomit ke storan.
  • Nod yang ketinggalan mengesahkan semula segala-galanya: setiap sijil, setiap bundle dan bukti panggilan, setiap resit, sebelum ia menerima blok yang disegerakkan. Tandatangan kemuktamadan tidak pernah dipercayai sebagai ganti bukti.

Helaian rujukan pemulihan, daripada fullnode sendiri: ketinggian yang tidak bergerak dengan peer_count yang rendah ialah masalah rangkaian; ketinggian yang tidak bergerak sedangkan rakan sebaya baik-baik sahaja bermakna kurang daripada 2/3 stake dalam talian; CORRUPT CHAIN semasa permulaan bermakna nod memotong hujung yang rosak dan sedang menyegerak semula.

Disahkan kali terakhir terhadap commit fullnode c0878c3f (rantai 21) pada 2026-10-12. Jika kod dan halaman ini tidak selari, kodlah yang betul; sila maklumkan kepada kami.