この ページ は、証明マシンの規模を見積もるために使います。また、転送に1分以上かかる理由、スループットの上限が計算ではなくブロック空間で決まる理由、証明システムが変わると何が壊れるのかを理解するためにも使います。バリデータが受け入れるものはすべて、バリデータ自身が検証した証明に裏付けられています。
証明が述べること
チェーンが実行するすべてのプログラムについて、述べる関係は一つです。
この RV32IM プログラムは、
base_pcから開始し、H_INでコミットされたプライベート入力ベクトルとH_PUBでコミットされた公開入力セグメントを用いて実行され、2ᵗ − 1サイクル以内に停止し、消費したガスは高々GAS_LIMITで、次の8つの出力ワードを公開した。
プログラムは回路内ダイジェスト hc で識別されます。検証者が命令ワードを目にすることはありません。シールドされた転送とは、この関係を隠しアセットバンドルゲストに適用したものです。これは手作業でアセンブルされた4入力4出力のプログラムで、その hc はジェネシスファイルに hc_bundle として固定されています。チェーン 20 はゲスト v3(guests::bundle_hidden_v3、60af094a…6e3fce、チェーン 17 以降)を固定しています。チェーン 14 と 15 は v1(83d3a370…cd0ef8)、チェーン 16 は分岐のない v2(651043e2…839b)を固定していました。チェーン 17 以降、すべてのバンドルは2つ目の証明、すなわち認可ゲスト(guests::auth、ジェネシスの hc_auth、1e4e347f…5639c1)の証明も備えています。バンドル証明は閲覧鍵を入力に取り、認可証明は送信者がその背後にある支払い鍵を持っていることを示します。これが分割認可であり、閲覧鍵のみを持つペアリング済みの証明者がバンドル証明を作成できる理由です。隠しアセットゲストは、チェーン 13 までの2入力2出力の bundle ゲストに置き換わりました。後者はテスト用にのみフルノードに残っており、どのチェーンも固定していません。機密呼び出しとは、同じ関係をデプロイ済みプログラムに適用したものです(Programs)。
ウォレットがバンドルを証明する方法
rand send <rand1…> <amount> はプライベートな処理をローカルで行い、チェーンに届くのは証明、コミットメント、ナullifier、封印されたエンベロープだけです。
- 閲覧鍵でツリーをスキャンし、入力を選びます。金額と手数料をまかなう RAND ノートを最大2つ(スロット 2〜3)選びます。トークンの転送またはバーンでは、そのトークンのノートを最大2つ(スロット 0〜1)選び、RAND ノートは手数料のみをまかないます。使われない入力スロットはダミーです。金額は 0、所有者はウォレット、メンバーシップの失敗は回路内でマスクされ、ナullifier は変わらず公開されます。ゲスト v2 以降、ゲストは分岐がありません。ダミーのパスも実際のノートと同様に、32 レベルすべてを通ってハッシュされます。
- ヘッドアンカー(
rand_getAnchor)と、各実入力の 32 レベルの Merkle ウィットネス(rand_getWitness(index))を取得し、返されたルートをアンカーと照合します。 - 4つの出力を構築します。価値が移動するグループでは、受取人のノートとお釣りのノート(ゼロでも必ず存在します)を作り、それ以外はゼロ金額のダミーとし、使い捨て鍵に封印します。
- 各出力をエンベロープに封印し(受取人宛ての ML-KEM-768 と、ウォレットの
ovkで包んだトランザクション鍵)、アクションとともにトランザクション全体を組み立て、そのバインディングを取ります。バインディングは、証明を空にしたトランザクションに対するblake3("rand-tx-bind-1" || …)で、8ワードです(Transactions)。ジェネシスがbinding_domain: 1を設定しているチェーン 20 では、ジェネシスハッシュ、次いでチェーン ID を先頭に置いたblake3("rand-tx-bind-2" || …)になります。そのため、あるチェーン向けに作った証明は、同じチェーン ID を持つチェーンを含め、他のどのチェーンでも検証を通りません。v0.6.8 より古いウォレットは旧バインディングを使うため、チェーン 20 はその証明を拒否します。 - 認可します。新しい 256 ビットのソルトを引き、16 ワードのプライベート入力(支払い鍵とソルト)に対して、バインディングを公開入力セグメントとして、ティア 10 で認可ゲストを証明します。支払い鍵から
nkを導出し、c = H(AUTH, nk ‖ salt)を公開します。バンドルはこれをauth_commitとして持ちます。 - 1,212 ワードのプライベート入力(閲覧鍵
nk、パス付きの4つの入力スロット、アンカー、4つの出力、fee、burn_a、burn_r、プライベートアセットA、time、ソルト)に対して、同じバインディングを公開入力セグメントとして、ティア 14 でバンドルゲストを証明します。この証明は、所有権、メンバーシップ、各実入力がそのスロットのアセットを持つこと、4つのナullifier、同じc、そして2つの収支in₀ + in₁ = out₀ + out₁ + burn_aとin₂ + in₃ = out₂ + out₃ + fee + burn_rを示します。これはペアリング済みの証明者がウォレットに代わって作成できる証明です。認可証明はウォレット自身のマシンで作成されます。 - 証明が公開したダイジェストを、平文から計算したダイジェストと照合し、
Transaction { chain_id, bundle, action: None }を送信します。
チェーン 14 以降、順序が重要です。証明はエンベロープとアクションにコミットするため、これらは証明より先に存在していなければなりません。呼び出しでは、呼び出し証明が最初に作られ、これもバインディングの内側に入ります。hardening_v6 チェーンでは、呼び出し証明自体が、2つの証明を空にしたトランザクションの呼び出しバインディング(チェーン 16〜19 では rand-call-bind-1、チェーン 20 ではジェネシスハッシュ付きの rand-call-bind-2)に対して作られます。これには手数料バンドルのナullifier が含まれるため、別のバンドルの下にコピーすることはできません。
proving bundle (tier 14; about a minute on a laptop)…
proved in 98.3s: tier 14, 1423170 bytes
submitted transfer 4f2c… 1.5 RAND out, 98.499 RAND change, fee 0.001 RAND, anchored at height 192
このトランスクリプトは、チェーン 14 時点のフルノードのガイドにあるウォレットの出力形式です。表示されているバイト数は、チェーン 14 でコミットされたプロダクションプロファイルのバンドル証明のものです。チェーン 17 以降のウォレット(チェーン 20 の v0.6.8 を含む)は、これらの行の前に2行、proving the spend authorisation on this machine (tier 10; seconds)… と authorisation proved in …: tier 10, … bytes を表示し、バンドルの行の文言を proving the bundle (tier 14; about a minute and a half on a laptop)… としています。
すべてのアクションは同じ仕組みで支払われ、バンドルは常にちょうど1つです。デプロイ、呼び出し、トークン登録、トークンミントは RAND のゼロ値の自己転送に載り、ボンドはステークを burn_r でバーンするバンドルに載ります。トークンバーンとブリッジバーンは、スロット 0〜1 からアセットをバーンし(burn_a、burn_asset)、スロット 2〜3 から RAND の手数料を支払う1つのバンドルに載ります。転送が動かすアセットはウィットネスワードであり、どの公開フィールドにも現れません。
コスト
開発用ラップトップ(Apple Silicon、リリースビルド)での実測値で、フルノード自身のドキュメントが記録している数値です。
| ゲスト | ワード数 | サイクル数 | ティア | 証明 | 証明サイズ(プロダクション、80 クエリ) |
|---|---|---|---|---|---|
| バンドルゲスト v3(チェーン 17〜20) | — | ティア 14 の予算内に 4,024 サイクルと 273 回の Poseidon2 置換の余裕 | 14 | ≈ 100 秒、ピーク 5.7 GB。チェーン 18 での実測は 102.5〜134.0 秒(2026-09-30) | ≈ 1.50 MB。チェーン 18 での実測は 1,494,151〜1,504,260 バイト(2026-09-30) |
| 認可ゲスト(チェーン 17〜20) | — | 250 | 10 | ≈ 7 秒。チェーン 18 での実測は 6.6〜19.9 秒(2026-09-30) | ≈ 1.37 MB。チェーン 18 での実測は 1,364,940〜1,375,371 バイト(2026-09-30) |
| 隠しアセットバンドル v1、4入力4出力(チェーン 14 と 15) | — | ティア 14 の予算内で、約 2,071 サイクル(13%)の余裕 | 14 | ≈ 98〜100 秒、ピーク 5.7 GB | ≈ 1.43 MB。チェーン 14 での実測は 1,422,116 バイトと 1,423,170 バイト |
bundle、2入力2出力(廃止。チェーン 13 まで) | 3,811 | ≈ 9,160 | 14 | ≈ 100 秒(単独で 94.6〜97.9 秒。2つ同時では各 114 秒) | チェーン 8 での実測は 1,321,773 バイト |
private_payment(呼び出し) | 小 | < 1,000 | 10 | ≈ 7 秒 | ≈ 1.37 MB(ティア 10 の fib:制約セット 7 で 1,367,688 バイト、セット 6 で 1,298,729 バイト) |
| ハッシュテーブルなしの呼び出し(オフチェーン台帳、チェーン 18) | 773 | — | 14 | 114.8 秒 | 1,498,589 バイト |
| SHA-256 テーブル付きの呼び出し(負債の証明、チェーン 18) | 994 | — | 14 | 122.9 秒 | 1,911,152 バイト |
| Keccak テーブル付きの呼び出し(匿名投票、チェーン 18) | — | — | 12 | 29.2 秒 | 3,346,865 バイト |
検証は、すべてのノードが負担するコンセンサスコストです。ウォームな検証鍵があれば約 16 ms、ある形状に対して初めて鍵を構築するときは約 230 ms です。検証鍵はプログラムの内容に依存せず、(tier, program_log_height, input_log_height, keccak_log_height, sha256_log_height, public_log_height) をキーとします。そのためノードは形状ごとに1つ構築して再利用します。デプロイ済みプログラムの鍵は、デプロイ時にバックグラウンドで一度だけ計算されます(ラップトップで約 2 秒、2 vCPU のサーバーで 7 秒)。チェーン 13 以前の2入力2出力バンドルは、形状 program 12, input 10, keccak 0, sha256 0, public 2, mem 16 を宣言していました。チェーン 14 のバンドル証明は、8つのバインディングワードの高さである public 4 を宣言し、どちらのハッシュテーブルも持たず、別のティア、いずれかのテーブル、または別の公開高さを宣言した場合は、検証鍵が構築される前に拒否されます。制約セット 7 以降、宣言されるすべてのテーブルは少なくとも 2⁷ 行を持つため、チェーン 20 のバンドル証明は public 7 を宣言します。
チェーン20のトランザクション1件は、バンドル証明と認証証明を合わせて約2.87 MBの証明を伴い、呼び出しではさらに3つ目の証明が加わります。各証明は、ジェネシスの max_proof_bytes に収まらなければなりません。チェーン20では4,194,304(4 MiB)で、チェーン17〜19と同じです。チェーン13〜16では8 MiBでした。
隠しアセットのguestがティア14に収まるのは、非公開入力をループで読み込み、Merkle検証の兄弟ノードの読み込みを融合しているからです。従来のループ展開スタイルで書くと、同じ関係はティア16になり、約400秒、21〜22 GBを要するため、16 GBのウォレットは対象外になってしまいます。
証明はCPUに律速され、現在ウォレットはすべてのプラットフォームでCPUバックエンドを使用しています。大規模ティアの実行では証明者はシングルスレッドで動作しました。16 vCPUのドロップレットでも1コアの99%で動作し、証明が完了するかどうかを決めたのはコア数ではなくメモリでした(証明のメモリ)。send、bond、call、deploy、bridge-mint、bridge-burn の --cuda フラグは、--features cuda を付けたビルドが必要なNVIDIAバックエンドを選択します。そのカーネルは2026-09-28に実機のNVIDIA H100で初めて動作し、CPUのリファレンスと一致しました。ただし、リリースがvendorするcircuitsのチェックアウトにはPTXがコミットされていないため、カーネルをコンパイルするまでビルドは no PTX for the GPU kernels で失敗します。フリートのGPUノードで測定された本番の証明はまだありません。CPUへのフォールバックは意図的に設けていません。また、saltが証明者の外に出ることはないため、CUDAによる呼び出しは入力エンベロープを封印できません。ティア14の隠しアセットのバンドル証明のピークメモリは約5.7 GB(Production FRI、CPU)です。より大きなメモリクラスは、後述のインタプリタ証明と再帰証明に関わるものです(64 GB以上)。
ノードによる検証の方法
受理では、まず軽いチェックを行い(トランザクション)、続いて次を行います。
- 公開された平文(アンカー、4つのnullifier、4つのコミットメント、
fee、burn_a、burn_r、burn_asset、time、バンドルのauth_commit、およびゼロに固定されたtaintワード)からバンドルダイジェストを再計算し、証明が公開したものと等しいことを要求します。ウィットネスが関係を破った証明は、どの平文とも一致しないtaintされたダイジェストを公開します。一方、構造的に担保されるチェックもあり(guestが出力の送信者、アセット、時刻を自ら与えるため、証明者はそれらを選べません)、非公開アセットはダイジェストに含まれません。 - 証明をデコードし、宣言された高さをティアと照合します(
check_declared_heights)。これにより、証明の形状に対するチェーンの上限は検証者側のものになります。署名や証明を検証する前に、送信またはゴシップされたすべてのトランザクションに対して正規証明のスクリーニングが実行されます(hardening_v6の下ではブロック検証でも実行されます)。fullnode v0.6.8(audit v6、ZKV-4)以降、このスクリーニングはまず宣言されたすべてのdegreeを25ビット(MAX_HONEST_DEGREE_BITS、メモリテーブルの上限に1を足したもの)で制限します。そのため、巨大なdegreeを持つヘッダーが、正直な畳み込みスケジュールを再導出する間ノードを拘束することはなくなり、スクリーニング内のパニックはノードを停止させず、そのトランザクションを拒否します。 - トランザクションのバインディングを計算し、
Machine::verify_public(hc_bundle, &binding, proof)を実行します。これはバッチ検証器に、H_PUBがその8ワードのダイジェストであることの検証を加えたものです。したがって、別のアクション、別のエンベロープ、別のチェーンidのトランザクションにコピーされた証明、またチェーン20では別チェーンのジェネシスにコピーされた証明は、検証を通りません(チェーン13まではセグメントが空で、証明をトランザクションに結び付けるものはありませんでした)。 - 認証証明を
hc_authと同じバインディングに対して検証し、それが公開するcがauth_commitと等しいことを要求します。認証証明のないバンドルは拒否され(AuthMissing)、cが異なるバンドルも同様です(AuthMismatch)。 - バンドル証明の
GAS_LIMITがジェネシスのbundle_gas_limit(20,479)と等しいこと、認証証明のものが1,279と等しいことを要求します。これらは2つのguestのヘッダー上限です(BundleGasLimit、AuthGasLimit)。 - 呼び出しでは、プログラムに保存された
code_hashに対して同じことを行います。セグメントには、プログラムの公開ワードに呼び出しのバインディングを続けたものを使います(RPL-2のInvokeは、その遷移をコンテキストワードとして追加します。プログラム)。そのうえで、証明が宣言するガスリミットとそのバイト数に対して手数料を検査します(手数料)。
RPCまたはゴシップで送信されたトランザクションは、64件のキューの背後にある4つのワーカーのいずれかで、コンセンサスループの外で検証され、検証を通った後にのみ他のノードへゴシップされます。ピアごとのトークンバケット(バースト16、毎秒4の補充)が、ピアがノードに検証させられる量を制限し、8,192エントリのキャッシュが、恒久的に拒否されたトランザクションの再送にコストなしで応答します。提案されたブロック内の証明の検証は、ブロックの適用時にコンセンサスループ上で引き続き実行されます。同期するノードは、ブロックを受け入れる前にすべてのブロックのすべての証明書とすべての証明を再検証します。クォーラムが署名したからという理由で信頼されるものはありません。
ティア
| ティア | サイクル予算(2ᵗ − 1) | CPU行 | 用途 |
|---|---|---|---|
| 10 | 1,023 | 2¹⁰ | 認証guest、private_payment、fib |
| 12 | 4,095 | 2¹² | |
| 14 | 16,383 | 2¹⁴ | 隠しアセットのバンドルguest(および廃止された bundle guest)、最大の呼び出し |
| 16 | 65,535 | 2¹⁶ | テストスイートのEVM呼び出し証明、変換されたERC-20の approve(チェーン13で呼び出し) |
| 18 | 262,143 | 2¹⁸ | ERC-20の transfer と transferFrom(変換版、またはインタプリタ版) |
| 20 | 1,048,575 | 2²⁰ | SPL Token(変換版、またはsBPFインタプリタguest上) |
fullnode v0.5.6(2026-09-25)以降、ティア14を超える呼び出しの証明は、検証鍵が構築される前に拒否され(CallTierTooHigh)、それを含むブロックは無効になります。また、1回の呼び出しに含められるのは、Keccak-f置換128回、SHA-256圧縮128回までです。ティア16〜20の証明は引き続き可能ですが、オフチェーンに限られます。これらより上の行はチェーン20ではいずれも呼び出せず、チェーン20は、ティア14の呼び出しに収まらないほど大きいプログラム、すなわち公開入力なしで8,180ワードを超えるプログラムのデプロイを拒否します(ProgramUncallable)(予算)。
証明者は、サイクル数にプログラムと入力ダイジェストの行を加えた分を賄える最小のティアを選びます。収まらない実行は、証明の前に失敗します。公開されるのはティアのみです。ティアが1つ上がるごとに、証明時間はおよそ4倍になり、証明サイズはわずかに増えます。チェーン20では、呼び出しの手数料はティアではなく、証明が宣言するガスリミットとそのバイト数に従います(手数料)。
制約セットとハードフォーク
制約セットとは、検証器が検査するテーブル、列、バス、公開値、FRIパラメータの正確な集合です。あるセットで作られた証明は、どちらの方向でも別のセットでは検証を通りません。また、ノードの起動時のリプレイはチェーン内のすべての証明を再検証するため、異なるセットからビルドされたノードは最初の証明で失敗し、切り詰められます。このため、セットの変更はすべて、すべてのノードが1つのビルドに揃った新しいチェーンidとして切り出されます。また、rand_status が hc_bundle と hc_auth を報告し、ビルドがジェネシスと一致しないノードが起動を拒否するのも、そのためです。
| セット | 日付 | 変更点 |
|---|---|---|
| 2 | 2026-09-10 | 最初のレビュー後の5件の健全性修正 |
| 3 | 2026-09-11 | Poseidon2チップ、回路内の hc、ウィットネスとしてのプログラムテーブル、サブワードメモリ、RV32M、FRIを27クエリに再調整 |
| 4 | 2026-09-11 | 専用テーブルを持つsalt付き入力コミットメント H_IN、フラットバイナリローダー |
| 5 | 2026-09-12 | オプションの keccak テーブル、証明が宣言するメモリ高さ、zk監査による2件の重大な修正、FRIを80クエリに戻す、MAX_PROOF_BYTES を2 MiBに |
| 6 | 2026-09-14 | 必須の public テーブルと H_PUB、オプションの sha256 テーブル、ライブラリとしてのEVMおよびsBPFインタプリタguest、34個の公開値。チェーン12〜15が実行していたもの。 |
| 7 | 2026-09-28 | BLIND バスによるすべてのLogUp終端のブラインド化、宣言されたすべてのテーブルを2⁷行以上に下限設定、入力・公開・saltワードの32ビット範囲チェック、POSEIDON2_LEN システムコール(7)、JALR はターゲットのビット0をクリアし funct3 = 0 を要求、key_derivation_v2 によるsalt付き検証鍵。チェーン16と17が実行していたもの。 |
| 8 | 2026-09-29 | ガスメーター:cpuテーブルの GAS 列と公開値 GAS_LIMIT、35個の公開値。チェーン18〜20が実行しているもの。 |
チェーン14と15では制約は変わっていません。チェーン15のノードは、Poseidon2の86個のラウンド定数を、シードによる生成ではなくリテラルのテーブルとして保持します(audit ZKV-2)。値は同じなので、ハッシュ、ダイジェスト、証明は動いていません。チェーン14では、隠しアセットのバンドルが新しいguest(新しい hc_bundle)となり、トランザクションのバインディングには、セット6がすでに回路内でバインドしている公開セグメントを使います。それでもこれはハードフォークです。バンドルのワイヤーフォーマット、固定されたguest、すべてのトランザクションidが変わり、バンドルを含むチェーン13のトランザクションは新しいビルドに拒否され、フォーク前にビルドされたウォレットは、チェーンが拒否する空セグメントの証明を生成します。
ここ3つのチェーンは、それぞれ「証明とは何か」を変えました。チェーン16(fullnode v0.6.1、2026-09-28)は制約セット7へ移行し、分岐のないバンドルguest v2を固定して hardening_v6 を設定しました。2026-09-27のレビューで、短いテーブルとブラインドされていないLogUp終端が非公開データを漏らすことが判明したためです(How the zkVM works)。すべての検証鍵が変わりました。チェーン17(v0.6.3、2026-09-29)は制約セット7を維持したまま、分割認可を追加しました。バンドルguest v3、auth guest、バンドルのワイヤ形式に加わる2つの新フィールド、そしてトランザクションIDドメイン rand-txid-3 です。チェーン18(v0.6.7-rc1、2026-09-29)は、ガスメーターのために制約セット8へ移行しました。証明サイズに対する実測コストは1%未満です。チェーン19(2026-10-01)は、同じv0.6.7ビルドによるチェーン18の再ジェネシスであり、証明には何も変更を加えていません。チェーン20(fullnode v0.6.8、2026-10-01)は制約セット8と同じguestおよび検証鍵を維持しつつ、証明が何に束縛されるかを変更します。トランザクションとコールの束縛にジェネシスハッシュを含め(binding_domain: 1)、これはウォレットと台帳が計算するパブリック入力であるため、回路自体は変わっていません。それでもハードフォークです。v0.6.7のウォレットが生成した証明は、このチェーンでは検証を通らないためです。各ビルドは、ジェネシスハッシュによって、それ以前のチェーンを拒否します。
コード内に記載されている監査上の注記が2点あります。1つ目は、TIER パブリック値は、検証者が証明ヘッダーおよびバッチのdegree bitsと照合して検査しますが、回路自体は制約していないことです(監査ZL1。パブリック値のレイアウトがずれるため、修正せず次のセットに向けた指摘事項としています)。2つ目は、H_IN はguestから見えるコミットメントであり、検証者は呼び出し側が与えた値とは比較しないことです。これは設計によるものです。
今後の予定:ブロック集約
チェーン14と15では、隠しアセットのバンドル証明が1件あたり約1.43 MBでした。そのため、4 MiBのブロック(デフォルトであり、チェーン12の値)に収まるシールドされた送金は2件でした。2入力2出力のバンドルの約1.3 MBであれば3件でした。チェーン13、14、15ではブロック上限を20 MiB(max_block_bytes)に引き上げ、14件を収められるようにしました。チェーン20も20 MiBを維持していますが、そこでの送金1件には約2.87 MBの証明が付くため、1ブロックに収まるのは約7件です。fullnodeが(2026-09-12に)プルーニングやブロックの拡大ではなく選んだ対処法が、ブロックレベルの集約です。封印されたウィンドウごとに、N件のバンドル証明を検証する再帰証明を1つ生成します。これにより、履歴は端から端まで証明を伴ったまま保たれ、元の証明は破棄できます。これは実装・マージ済みですが、有効化されていません。しかも、チェーン14以降は、有効化の前に再計測が必要です。許容されるバンドルの形状は空のパブリックセグメント(public 2)で計測されたものでしたが、トランザクションに束縛されたバンドルは public 4 を宣言するため、チェーン14で証明されたバンドルは1つも一致しません。制約セット7と8で形状はさらに変わりました。現在のバンドル証明は public 7 を宣言して35個の値を公開するため、集約のインターフェースは証明1件につき35ワードです。ノードビルドは、aggregation セクションを持つジェネシスでは起動を拒否し、チェーン14から20は、このセクションなしでカットされました。チェーン20のように動的なガス価格を持つジェネシスも、aggregation セクションと併存する場合は拒否されます。fullnode v0.5.8以降、集約証明はその集約者にも束縛されます(監査AGG-2:プログラムが aggregate_binding(chain_id, aggregator, nonce) をabsorbします)。そのため、許容される形状のプログラムダイジェストは、この変更を含むビルドで計測する必要があります。有効化はさらに、修正済みの再帰検証器に対する偽造集約のエンドツーエンド検証がまだ実施されていないこと、そしてauth証明に関する判断を待っています。集約プログラムが検証するのはバンドル証明のみであるため、分割認可のチェーンでウィンドウを封印しても、送金1件あたりは約2.87 MBから約1.37 MBに縮小するだけで、ゼロにはなりません。
実装済みの内容は次のとおりです。
- 2つ目のGoldilocksネイティブなマシン(再帰VM、
randprotocol-rvm)。その検証プログラムは、tier 21でRV32証明を約197万行(制約セット7では2,044,506行)で検証します。加えて、バンドル証明のウィンドウに対するN汎用の集約プログラムがあります。 - 2つのロール。validatorはCPU負荷を低く保ち、封印されたブロックごとに集約を1つ検証します。aggregator(許可不要で、ボンドを預け、シールドされた支払先アドレスを持つ登録制)は、GPU級のマシンで集約を証明し、対象となるバンドルのproving分の取り分に加えて、半減スケジュールに従って新規発行されるRANDのブロック補助金を受け取ります。
- 5つのアクション(
RegisterAggregator、UnbondAggregator、WithdrawAggregator、SlashAggregator、Aggregate)。SlashAggregatorはワイヤ上に残っていますが拒否されます。再試行された集約は同じnonceで再署名されるため、二重署名には当たらないからです。さらに、9段階の受け入れ処理、対象となったバンドルを各約3 KBのパブリックフィールドまでプルーニングする封印、新規ノードにウィンドウごとに再帰検証1回のコストで済む封印形式の同期、RPCメソッドrand_getAggregate、rand_getAggregators、rand_getUnsealed、rand_getRawTransaction、そしてrand-node aggregate --watchデーモンがあります。
テストFRIプロファイルでの実測値は次のとおりです。N=1の集約1件は、負荷のかかったノートPCで約26分で証明されました(327,035バイト)。新規ノードは、7ブロックの封印バッチを再帰検証1回で、1秒未満で適用しました。マシンクラスは当初の見積もりでは、N=1にはホストメモリが64 GB以上、N=2には128 GB以上、N=3には160 GB以上が必要です。本番でのN ≥ 2はCUDAバックエンドの領域であり、そのためにはまだ存在しないGPUノードが必要です。制約セット7での256 GBマシンの実測(2026-09-28および29)では、N=2の集約に133 GB、N=3に221 GBを要し、本番の終了証明(1件の内部証明に対する検証プログラム)は256 GBを超えました。いずれも制約セット8では再計測していません。集約が有効化されるまで、チェーン20では集約が証明の代わりになることはありません。2つのアーカイブノードがすべての元の証明を保持し、validatorは24時間より古い履歴をプルーニングします。