Rand Protocol
ドキュメント
ガイド

ノードの運用

バイナリのビルド、鍵の作成、chain 20 のジェネシスからのデータディレクトリの初期化、ブートストラップへの接続、RPC のバインド、履歴のプルーニング、チェーンの検証までを、オブザーバーまたはバリデーターとして行う手順を説明します。

このページでは、testnet に対して自分の rand-node を動かす方法を説明します。これはウォレットをプライベートに使うための推奨の方法でもあります。自分で動かすノードなら、どのリーフを使おうとしているかが自分以外に知られることはありません。オブザーバーは同期し、すべての証明を再検証して、JSON-RPC を提供します。バリデータも同じことを行い、さらに自分の鍵がエポックの集合に入ると、コンセンサスにも参加します。

ビルド

必要なもの: Rust 1.98.1(rust-toolchain.toml で固定されています。rustup がインストールします)、C++ コンパイラ、RocksDB 用の cmake。zkVM クレートは、証明システムのリポジトリ(randprotocol/zkp-circuits)の兄弟ディレクトリ circuits/ のチェックアウトへのパス依存を持ちます。このチェックアウトは fullnode/ の隣に置き、リリースがベンダリングされたコミットに合わせる必要があります。そのコミットは crates/randprotocol-zkvm/guests-compiled/PROVENANCE.md の circuits: 行に書かれています(v0.6.7 と同じく、v0.6.8 では aeacf31 です)。初回のビルドには 10 分から 20 分かかります。

git clone https://github.com/randprotocol/fullnode
cargo build --release          # target/release/rand-node, target/release/rand, target/release/rand-prover

v0.6.8 を実行してください(git checkout v0.6.8、コミット c9c9bd3c。フリートが動かしているリリースです。ノードの sha は rand_getVersion で確認できます)。この GitHub リリースには rand-node、rand、rand-prover、SHA256SUMS が含まれます。これらは 1 台のフリートホストでビルドされたもので、署名はありません。Chain 20 にはこのバージョンが必要です。そのジェネシスには、これより前のビルドが読み取らないフィールド(testnet、binding_domain、proof_window_blocks、program_state、ブリッジの rotation グループと fees グループ、gas の上限、投票によるステーキング受け入れ)が含まれており、v0.6.8 には古いノードが実行しないコンセンサスの変更も含まれているためです。証明は、chain 18 と 19 のときと同様に、引き続き制約セット 8 のもとで作成されます。またすべてのバンドルは、バンドル証明のほかに認可証明も引き続き持ちます(chain 17 以降の分割認可)。そのためジェネシスは同じ 2 つのゲストを固定します。バンドルゲスト v3(hc_bundle 60af094a…)と認可ゲスト(hc_auth 1e4e347f…)です。ジェネシスには gas セクション、hardening_v6、envelope_bytes も含まれます。v0.6.8 のビルドは、chain 14、15、16、17 のジェネシスを、ハッシュによって run でも verify でも拒否します。chain 19 のジェネシスは引き続き実行できます。すべてのノードはフリートのビルドを使います。

Chain 20: 全停止型ハードフォーク

Chain 20 は 2026-10-01 の 06:17 UTC に稼働を開始しました。chain 19 のスナップショットから作られ、全停止・全起動の方式で切り替えられました。chain 19 のすべてのノードが高さ 7,700 で停止し、すべてのノードが v0.6.8 で chain 20 を起動しました。ローリングアップデートではなかったのには、2 つの理由があります。1 つは、chain 20 が新しいジェネシスであり、chain 19 とは共有するブロックがないことです。もう 1 つは、v0.6.8 に audit v6 によるコンセンサスの変更が含まれており、これをノードごとに順次適用してはならないことです。CON-4 はバリデータのロックの自動解除を廃止し、CH-1 はタイムアウト証明書によるペースメーカーを追加します。26 のバリデータすべてと、その鍵、ピア ID、ブートストラップが引き継がれました。クォーラムは引き続き 26 のうち 18 です。Chain 19 と chain 18 は廃止されました。

したがって、ノードを chain 19 から chain 20 へ移行するには、以下のとおり、新しいバイナリ、新しいジェネシスファイル、新しいデータディレクトリが必要です。chain 20 で送金するには、ウォレットが v0.6.8 である必要があります。 そのジェネシスは、すべての証明とすべての署名付きメッセージを自身のハッシュに結び付けます(binding_domain: 1)。古いウォレットはこれを行いません。

鍵

rand-node keygen --out node.key.json      # prints the address
rand-node address --key node.key.json     # address, public key, libp2p peer id

ファイルの形式は { "seed", "address", "public_key" } で、パーミッションは 0600 です。秘密なのはシードだけです。オブザーバーにも鍵が必要です。それは p2p の識別情報になります。ノードの鍵はウォレットの鍵ではありません。ウォレットには rand keygen を使ってください。

鍵は自分で生成し、チェックアウトの外に保管してください。fullnode のリポジトリは、もう鍵を一切追跡していません(audit v3、OPS-1)。chain 8 から 13 のためにコミットされていた deploy/node-*.key.json と deploy/payout/*.key.json のファイルは、公開されたシードであり、使ってはなりません。Chain 20 のバリデータ鍵はリポジトリの外で生成され、リポジトリに入ったことは一度もありません。26 のジェネシスバリデータは、chain 14 のために生成された 18 個の鍵と、chain 15 でボンドされた 8 個の鍵で、以後のすべての切り替えを通じて引き継がれてきました。

v0.6.8 以降、rand-node keygen は、すでに存在するファイルを --out に指定すると拒否します。v0.6.7 は確認なしに上書きしていました。このファイルはシードの唯一のコピーです。ボンドがこれに依存する前に、バックアップを取ってください。

ジェネシスから初期化する

チェーン上のすべてのノードには、バイト単位で同一のジェネシスファイルが必要です。rand-node init はそれをデータディレクトリにコピーしてハッシュを出力します。chain 20 では、そのハッシュが 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135 でなければなりません。ファイルは deploy/genesis-chain20.json(sha256 0020247a…3a21)です。これはタグの後に、ローンチ記録とともに fullnode の main にコミットされたため(コミット 74cfaca0)、v0.6.8 のチェックアウトには含まれていません。main から取得してください。

git -C fullnode show origin/main:deploy/genesis-chain20.json > genesis-chain20.json
rand-node init --datadir ./data-6210cf07 --genesis genesis-chain20.json

これにより <datadir>/db(RocksDB)が作成され、ブロック 0、ツリーの最初のリーフとなる 9 つのジェネシスノート(chain 19 から引き継いだ 5,184.243719258 RAND のオペレータウォレットを持つ 7 つの RAND ノートと、10 zUSD と 89 zUSD の 2 つの zUSD ノート。この 99 zUSD はブリッジのカストディにロックされています)、およびバリデータレジスタが格納されます。同じジェネシスで再実行しても何も起こりません。異なるジェネシスは拒否されます(already initialized with a different genesis は、そのデータディレクトリが別のチェーンのものであることを意味します)。フリートと同様に、データディレクトリにはジェネシスハッシュの先頭 8 文字を含めた名前を付けてください(data-<name>-6210cf07)。そうすれば、chain 19 のもの(-a3defc93)と衝突することはありません。

ジェネシスファイルの構造:

{
  "chain_id": 20,
  "timestamp_ms": 1790835251661,
  "validators": [ { "public_key": "<hex>", "stake": 1000000000000, "payout": "rand1…" } ],
  "alloc": [ { "cm": "<64 hex>", "envelope": { "kem_ct": "…", "to_receiver": "…", "to_sender": "…", "body": "…" }, "amount": 1000000000000,
               "opening": { "pk": "<64 hex>", "time": 0, "r": "<64 hex>" } },
             { "cm": "…", "envelope": { … }, "amount": 1000000000,
               "opening": { "pk": "<64 hex>", "time": 0, "r": "<64 hex>", "asset": 1 } } ],
  "faucet": true,
  "confidential": true,
  "fri_profile": "production",
  "hc_bundle": "60af094acfe65d85fdb18fb3d06cf9085dcf28c96e59e87f1ee527226e6e3fce",
  "bridge": { "emitter": "<64 hex>", "guardians": [ "<40 hex>" ], "emitters": { "2": "<64 hex>", "3": "…", "4": "…", "5": "…" },
              "pq_guardians": [ "<hex>" ], "pause_key": "<hex>",
              "rules_v2": { "global_mint_cap_per_window": 400000000000, "cap_window_secs": 86400 },
              "guardian_set_index": 1, "burn_sequence": 13,
              "min_inbound_sequence": { "2": 3, "3": 3, "4": 3, "5": 7 },
              "rotation": { "delay_secs": 86400, "needs_possession": true },
              "fees": { "mint_bps": 10, "burn_bps": 10, "recipient": "rand1…" } },
  "tokens": { "registration_fee": 1000000000, "mint_cap_per_day": 10000000000000,
              "tokens": [ { "name": "Shielded USD", "symbol": "zUSD", "salt": "<64 hex>",
                            "backings": [ { "chain": 2, "token": "<64 hex>", "decimals": 6 }, … ] } ],
              "max_tokens": 4096, "burn_registration_fee": true, "bound_note_value": true },
  "consensus_domain": 1,
  "staking": { "faucet_budget_per_epoch": "10000000000000", "bond_activation_epochs": 2,
               "max_weight_bps": 3333, "registration_v2": true,
               "faucet_recipients": [ "rand1…" ], "faucet_minters": [ "<validator address>" ],
               "max_stake_entry_bps_per_epoch": 2500, "admission_by_vote": true },
  "epoch_blocks": 1000,
  "max_program_words": 65535,
  "max_proof_bytes": 4194304,
  "max_block_bytes": 20971520,
  "max_call_envelope_bytes": 65536,
  "max_program_public_words": 32768,
  "envelope_bytes": 1860,
  "hardening_v6": true,
  "hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
  "gas": { "gas_price": "100", "byte_price": "800", "bundle_gas_limit": 20479, "metering": "circuit",
           "dynamic": { "target_block_bytes": 10485760, "target_block_gas": 262144,
                        "adjust_bps": 1250, "min_gas_price": "100", "min_byte_price": "800",
                        "max_gas_price": "10000", "max_byte_price": "80000", "byte_load": "paying" } },
  "testnet": true,
  "binding_domain": 1,
  "proof_window_blocks": 1024,
  "program_state": { "cell_fee": 10000000 }
}

すべてのフィールドがジェネシスハッシュに含まれます。hc_bundle はすべてのバンドル証明が照合されるバンドルゲストを固定し、hc_auth はすべての認可証明が照合される認可ゲストを固定します。異なるゲストを組み立てるビルドのノードは、起動を拒否し、両方のダイジェストを示します。5 つの max_* フィールドは任意で、存在する場合にのみハッシュに組み込まれます。chain 20 は 5 つすべてを設定しています。max_proof_bytes は 4 MiB で、chain 13 から 16 では 8 MiB でした。chain 17 以降、トランザクションは 3 つの証明(バンドル、認可、呼び出し)を持てるため、hc_auth を持つジェネシスでは、max_block_bytes を max_proof_bytes の 3 倍に 1 MiB を加えた値以上にする必要があります。各 alloc ノートは自身の opening(pk、time、r、トークンノートでは asset も)を持つため、ジェネシスノートの所有者と金額は設計上公開されています。Chain 20 には次のものがあります。

  • bridge セクション: インデックス 1 のガーディアンセット 1(ガーディアン 8 名)、ソースチェーン 2、3、4、5 のエミッタ(chain 19 のもの)、8 つの Dilithium2 pq_guardians、pause_key、burn_sequence 13、min_inbound_sequence(ソースチェーン 2、3、4 では 3、ソースチェーン 5 では 7)、そして rules_v2(24 時間のウィンドウあたり 4,000 zUSD のグローバルミント上限)。chain 20 での新規項目は次の 2 つです。rotation では、PQ ガーディアンまたは pause key のローテーションに新しい鍵による所有証明が必要で、コミットから 86,400 秒後に有効になります。fees では、チェーンがすべてのデポジットの 10 bps とすべてのバーンの 10 bps を、財務アドレス宛ての zUSD ノートとして受け取ります。そのため、デポジットは総額から手数料を引いた額をクレジットし、バーンは金額から手数料を引いた額を解放します。
  • tokens セクション: プロポーザーに支払われるのではなくバーンされる 1 RAND の登録手数料、バッキングごとに 1 日あたり 100,000 トークン(小数 8 桁)の mint_cap_per_day、4,096 トークンのレジストリ上限、2^63 のノート値の上限、そして 7 つのバッキングとともにジェネシスで登録された zUSD。99 zUSD がロックされており(Ethereum USDT 22、BSC USDT 22、Tron USDT 30、Solana USDT 25)、2 つのジェネシス zUSD ノートに対応します。
  • consensus_domain: 1: すべてのコンセンサス署名がこのジェネシスに結び付けられます(コンセンサス)。
  • staking セクション: faucet は 16 のウォレットと 18 のミントを行うバリデータ鍵に許可リストで制限され、エポックあたりの予算は 10,000 RAND、ボンド遅延は 2 エポック、重み上限は 3,333 bps、v2 登録です。ここまでは chain 19 と同じです。chain 20 での新規項目は、admission_by_vote(新しいバリデータ鍵は、バリデータセットが投票で承認した後にのみ登録されます)と、エポック境界ごとにアクティブな重みの 2,500 bps とする参入予算です。chain 19 では固定の 10,000 RAND でした(ステーキング)。slashing はありません。
  • gas セクション: 呼び出しは、その証明が宣言する gas 上限と自身のバイト数に対して支払います。価格は 1 gas あたり 100 単位、1 KiB あたり 800 単位から始まり、各ブロックの後に、目標である 10,485,760 バイトと 262,144 gas に対する充填率に応じて、1 ブロックあたり最大 1,250 bps で変動します。開始価格を下回ることはなく、chain 20 で新たに、10,000 と 80,000 を上回ることもありません。バイト価格の負荷にカウントされるのは、バイト価格が課されるバイト、すなわち呼び出しの証明と入力エンベロープだけです(byte_load: "paying")。すべてのバンドル証明は同じ上限 20,479 を宣言します(手数料)。
  • envelope_bytes: 1860: すべてのノートエンベロープはちょうど 1,860 バイトで、暗号化されたメモフィールドを持ちます。
  • hardening_v6: true: v0.6 のハードニングスイッチで、chain 16 以降のすべてのチェーンで設定されています。
  • testnet: true: faucet をブリッジセクションと併置できるようにするマーカーです。
  • binding_domain: 1: すべてのトランザクションの証明とすべての署名付きアクションメッセージにジェネシスハッシュが含まれるため、あるチェーンのために証明または署名されたものが別のチェーンで検証を通ることはありません。
  • proof_window_blocks: 1024: バンドルのアンカーは直近 1,024 個のブロック終端ルートのいずれかにでき、その time は高さより最大 1,024 ブロック遅れていてもかまいません(chain 19 では 256)。これにより、低速な証明者や委任された証明者に約 20 分の猶予が与えられます。
  • program_state、RPL-2: プログラムセル、プログラムボールト、Invoke アクション。invoke が作成するセルごとのセル手数料は 0.1 RAND です(上限については JSON-RPC を参照してください)。

aggregation セクションはありません。それを含むジェネシスでは、ビルドは起動を拒否します。

timestamp_ms はチェーンの時計のゼロ点です。独自の genesis を作成するときは、実際のローンチ時刻に近い値を設定し、決してそれより先の時刻にしないでください。過去に離れすぎていると、ブロック時間は壁時計より遅れ、1 ブロックあたり 60 秒というステップ上限によって追いつくまでその状態が続きます。未来に 15 秒を超えて離れていると、ブロック 1 はまったくコミットされません。リーダーのものを含め、すべての投票は、壁時計の時刻が genesis のタイムスタンプに達するまで保留されます。確認には、ファイルを作成したマシンではなく、フリートを起動するマシンの時計を使ってください。

実行

rand-node run --datadir ./data --key node.key.json \
    --listen /ip4/0.0.0.0/tcp/30303 --rpc 127.0.0.1:8545 --no-mdns \
    --bootstrap /ip4/164.90.239.200/tcp/30303/p2p/12D3KooWEQEbUwZRgqhDPXhW7vNBmcRcnhUDGUADe81VFdv3ALYe \
    --bootstrap /ip4/165.245.173.74/tcp/30303/p2p/12D3KooWJyc5oDHggAr89e9QrRFBy9Tg8TxXh18yzrb1SM6KKLYw \
    --bootstrap /ip4/188.166.235.187/tcp/30303/p2p/12D3KooWSyX84P1DAbWByLHpRBMLRWD53r3Jj4aqVt6tHoF8B2ZQ
引数デフォルト意味
--datadir必須初期化済みのデータディレクトリ
--key必須キーファイル:バリデータ ID、p2p ID、手数料の受取先
--listen/ip4/0.0.0.0/tcp/30303libp2p のリッスン multiaddr(複数指定可)
--bootstrapなし起動時、および未接続の間は 30 秒ごとに接続を試みるピア(複数指定可)
--rpc127.0.0.1:8545オペレーター用の JSON-RPC および WebSocket リスナー:すべてのメソッドを提供し、ループバックを信頼します。ループバックにとどめ、公開エンドポイントをここへ転送しないでください
--public-rpc <ADDR>オフv0.6.8:リバースプロキシや SSH フォワードの転送先となる、公開用の第 2 のリスナー。ビューイングキー系のメソッド、rand_mint、rand_getPeers を除いた固定のメソッドセットで、バッチなし、WebSocket なし、全呼び出し元で 1 つのメーターを共有します(JSON-RPC)
--rpc-viewing-token-file <PATH>オフv0.6.8:--rpc のビューイングキー系メソッドにベアラートークン(ファイルの 1 行目、32 文字以上)を要求します
--reserved-peer <PEER_ID>なしv0.6.8、複数指定可:受信接続数の上限を超えて受け入れられるピア。予約ピアを参照
--strict-gossipオフv0.6.8:有効な作成者署名、シーケンス番号、送信元を持つゴシップのみを受け入れます。ノードごとに順次適用できます
--validatorオフこのノードはバリデータキーを保持し、そのキーが現在のセットに含まれていればコンセンサスに参加します
--no-mdnsオフLAN ディスカバリを無効にします。サーバーでは推奨
--block-interval-ms1000提案どうしの最小間隔
--view-timeout-ms3000基本ビュータイムアウト。連続してタイムアウトするたびに倍増し、最大 8 倍まで
--verify-chainquick起動時の整合性チェック:off、quick(構造と台帳のリプレイ)、full(すべての署名と QC も)
--keep-raw-proofsオフブロック集約のアーカイブモード。chain 20 では効果なし
--prune-historyオフ(すべて保持)台帳を保持し、ブロック履歴はこの期間分のみ保持します:<n>m、<n>h、<n>d、最小 1h。testnet のバリデータは、2 台のアーカイブを除いて 24h で稼働しています。履歴のプルーニングを参照
--min-free-disk-mb1024データディレクトリのファイルシステムの空き容量がこれを下回る場合は起動を拒否します。空き容量がこの値の 4 倍未満になると rand_getHealth は disk_low を返します。0 でこのガードを無効にします
--prover <ADDR>オフこのアドレスで委任 prover をホストします。専用のリスナーであり、RPC ではありません。後述を参照
--gas-price, --byte-price100, 800gas セクションを持たないチェーンでの、呼び出しに対するプールの価格下限。chain 20 の genesis は独自の価格を設定するため、ノードはそこでは両方のフラグを無視し、警告をログに出力します

--prover-accept-spend-key は廃止されました。v0.6.8 のノードにこれを渡すと起動を拒否するため、v0.6.7 から引き継いだ unit ファイルからは削除してください。

上記の 3 つのブートストラップは、chain 19 から変わらずバリデータ C、D、E です。chain 20 は chain 14 用に生成されたバリデータキーで動作するため、そのピア ID は chain 14 で使われたものと同じです。p2p ID はバリデータキーから導出されます。ほとんどのバリデータは 1 日分のブロックしか保持しないため、genesis から同期するノードや、1 日以上遅れているノードには、全履歴を持つピアも必要です。2 台のアーカイブのいずれかを追加してください:

    --bootstrap /ip4/168.144.46.203/tcp/30303/p2p/12D3KooWS5usdMPvsbaWSaT2xtKndHvDYurwmueoNvaRRarb2wRf    # obs1
    --bootstrap /ip4/206.81.29.236/tcp/30303/p2p/12D3KooWPocyZGcNB9Vp68VSfgVvNXhSzBBoJa4h9R1yMkp71XHh    # rand-archive-2

--validator を省略するとオブザーバーとして動作します。起動の流れは次のとおりです。ストレージを開き、このビルドのゲストを genesis の hc_bundle および hc_auth と照合し、整合性チェックを実行し(破損した末尾は切り詰め、投票の安全性に関する状態は保持します)、永続化されたヘッドからコンセンサスを再開し、ネットワークと RPC を開始して、先行しているピアから同期します。RUST_LOG のデフォルトは info,libp2p=warn,libp2p_mdns=off です。Ctrl-C または SIGTERM(systemd の停止シグナル)で正常にシャットダウンします。同じ --datadir から再起動すると、永続化されたヘッドから再開します。

fullnode のトポロジー規則:NAT の内側にあるノードは、パブリックアドレスを持つノードへ外向きに接続します。パブリックノードでは TCP 30303 の受信を開放してください。ファイアウォールで保護されていない限り、RPC は 127.0.0.1 にバインドしてください。RPC は到達できる誰からでもトランザクションを受け付け、ビューイングキーを一度インポートした後は、そのポートを鍵を保持するものとして扱ってください。--block-interval-ms は 1000 以上(同じかそれより遅い値)に保ってください。バンドル証明には約 2 分かかり、そのアンカーは chain 20 では 1,024 ブロックの間有効です(chain 19 では 256)。

バリデータには同期された時計が必要です。 chain 14 以降、壁時計の時刻はコンセンサスの一部です(ブリッジ強化 B2)。親ブロックより 60 秒を超えて後のタイムスタンプを持つブロックは無効であり、バリデータは、自身の時計より 15 秒を超えて先のタイムスタンプを持つブロックへの投票を保留します。そのため、時計が遅れているバリデータは、障害をログに記録することなく投票を止めてしまいます。chain 20 では 26 台のうち 18 台が投票しなければコミットされません。すべてのバリデータで NTP を実行し、ノードを起動する前に確認してください:

timedatectl                     # want "System clock synchronized: yes" and "NTP service: active"
chronyc tracking
apt-get install -y chrony && systemctl enable --now chrony    # if it is not synchronised

予約ピア

v0.6.8 以降、ノードが受け入れる受信接続は、確立済みで最大 256、ハーフオープンで最大 64 です。libp2p の ID は無償で作成できるため、見知らぬ相手がすべてのスロットを占有し得ます。3 種類のピアが予約され、上限を超えて受け入れられ、同期バジェットのうちバリデータ用の割り当てから処理されます。すべての --bootstrap ピア、すべての --reserved-peer、そして署名済みピアバインディングから判明したすべてのバリデータ ID です。各 --validator ノードは自身の libp2p ID にバリデータキーで署名し、それをゴシップで伝えます。バリデータセットからそのキーを把握しているノードは、そのピアを予約し、再起動後もその記録を保持します。新規に作成したチェーンのストアにはバインディングがないため、最初のアナウンスが届くまでは前の 2 種類だけが予約されます。そのため、チェーンを作成する際は、フリートのバリデータのピア ID を --reserved-peer で渡すか、ブートストラップのリストに入れておいてください(rand-node address --key <file> はキーのピア ID を表示します)。rand_status.reserved_peers がその数を返します。フリートのノードでは、起動から 1 分以内にバリデータ数に達するはずです。

確認する

rand-node status                # rand_status verbatim
rand --rpc http://127.0.0.1:8545 status
rand peers

rand_status は次の項目を返します。height、view、syncing、sync_target、peer_count、connected_peers、reserved_peers、mempool_size、is_validator、active_validator、faucet、confidential、testnet、fri_profile、programs、notes、nullifiers、tree_root、hc_bundle、hc_auth、binding_domain、gas_prices、ノードの address と peer_id、同期の診断情報(sync_inflight_age_ms、sync_failures、sync_late_batches)、ディスク(disk_free_bytes、disk_low)、保持下限(prune_floor:すべてを保持するノードでは 0、prune_history_secs:未設定時は null)。chain 20 では、hc_bundle 60af094a…、hc_auth 1e4e347f…、faucet true、confidential true、testnet true、binding_domain 1、fri_profile "production"、そして 1 ガスあたり 100 から 10,000、1 KiB あたり 800 から 80,000 の範囲の gas_prices が見えるはずです。rand_getGenesisHash は 6210cf07…5135、rand_getVersion は 0.6.8 を返さなければなりません。

rand_getHealth は、空き容量が --min-free-disk-mb の 4 倍未満のとき、ok、syncing、behind よりも先に disk_low(free_bytes を伴う)を返します。

履歴のプルーニング

--prune-history 24h で起動したノードは、台帳(note、nullifier、アンカー、バリデータレジスタ、プログラム)をすべて保持し、それより古いブロック、その証明書、トランザクション、レシートを削除します。パスは 16 ブロックをコミットするごとに実行され、ヘッドのタイムスタンプからウィンドウを引いた時刻より古いブロックを最大 512 件削除します。genesis、ヘッド、およびその親は削除されることはなく、下限は上がる一方です。ディスク容量は RocksDB がコンパクションした後に戻ります。chain 20 では chain 19 と同様に、26 台のバリデータのうち 24 台が 24h で稼働し、約 1 日分のブロックを保持しています。chain 14 でプルーニングを有効にしたとき(2026-09-25)、各バリデータのブロックテーブルは、バックログが解消された後に 19 GB から 3.3〜4.4 GB に減りました。残りの 2 台、obs1 と rand-archive-2 は、2026-09-27 以降はバリデータでもあり、このフラグなしで稼働してすべてを保持しています。mainnet のノードはこのフラグを決して渡しません。

プルーニングされたノードで、下限より下の高さ指定の参照(rand_getBlockByHeight、高さ指定の rand_getFinality、下限に及ぶ rand_getBlocks または rand_getCompactBlocks の範囲)を行うと、data.floor を伴うエラー -32010 が返ります。アーカイブに問い合わせてください。ハッシュ指定の参照では、ノードがもう保持していないブロックに対して、存在したことのないブロックと同様に null が返ります。note と nullifier は決してプルーニングされないため、ウォレットのスキャンには影響しません。

プルーニングされたノードの起動時チェックは構造的なもの(ブロック 0 と保持されているブロック、その QC、親リンク、リーダー)であり、genesis からのリプレイではなく、自己修復も行いません。失敗した場合は、アーカイブから再同期してください。v0.5.7 より古いビルドでプルーニング済みのデータディレクトリを開く場合は、必ず --verify-chain off で実行してください。デフォルトのチェックは genesis からリプレイし、ブロック 1 が欠けていることを検出して、台帳を genesis まで切り詰めてしまいます。

prover のホスティング

chain 20 では、ウォレットはバンドルごとに 2 つの証明を作成し、大きいほうには約 6 GB のメモリが必要です。それを保持できないウォレットは、ペアリングした委任 prover にその証明を任せることができます。別個の rand-prover バイナリ、またはノードがホストする同じサービスです。

rand-prover --home /root/prover keygen
rand-prover --home /root/prover pair --name laptop --url https://prover.example.net
rand-node run --datadir ./data --key node.key.json --prover 127.0.0.1:8600 --prover-home /root/prover

pair は randprover: リンクを出力します。ウォレットは rand prover pair <link> でそのリンクを受け取り、その後はグローバルオプション --prover を通じて証明を行います。prover のリスナーは独立したものであり、RPC のメソッドになることはありません。--rpc と同じアドレスは拒否されます。--prover を指定した場合、<prover-home>/prover.key.json が存在し(デフォルトは <datadir>/prover)、かつ証明スロット 1 つあたり 5.74 GB に加えて 1 GiB のメモリが利用可能でなければ、ノードは起動を拒否します。--prover-max-parallel でスロット数を設定し、デフォルトは 1 です。

chain 20 では、prover に送られるのは spend key ではなく、ウォレットの viewing key と新しい salt です。認可証明は、ウォレット自身が spend key を用いて作成します。そのため、ペアリングされた prover はそのウォレットの履歴全体を読み取れますが、資金を使うことはできません。TLS を終端するプロキシを前段に置かない限り、リスナーは loopback に限定し、公開 RPC を提供するマシン上でホストしないでください。停止時には処理中の証明の完了を待つため、systemd ユニットには TimeoutStopSec=180 を設定してください。

Verify and repair

rand-node verify --datadir ./data                  # full: hashes, QCs, signatures, proofs, ledger replay, the supply counters
rand-node verify --datadir ./data --mode quick     # structure and ledger replay
rand-node verify --datadir ./data --repair         # truncate a damaged tail; peers resync the rest

先にノードを停止してください。終了コードは、整合していれば 0、問題が見つかり --repair が指定されていなければ 2 です。リプレイはすべてのバンドル証明を再検証するため、チェーンを生成したものと制約セットが異なるビルドでは、最初のバンドルで停止します。

Becoming a validator

validator は新しい genesis ではなく、ボンディングによって稼働中のチェーンに参加します。--validator を付けてノードを起動し、rand-node register --key node.key.json --payout <rand1…> --v2 で登録情報を出力します(chain 20 は v1 の登録を拒否します)。続いて、ウォレットから rand bond <address> 1000 --registration <hex> で 1,000 RAND 以上をボンドします。ボンドが有効化されると、ノードはブロックを提案します。chain 20 では、早くてもボンドから 1,000 ブロックのエポック境界を 3 つ越えた後です。chain 20 では、ボンドは二番目の手順になります。その genesis では staking.admission_by_vote が設定されているため、新しい鍵を登録するボンドは、投票重みの 3 分の 2 を超える validator がその鍵に投票するまで拒否されます。各 validator は rand-node admit sign --candidate <key or registration> --key <validator key> --genesis-hash 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135 で署名し、そのうちの 1 人が rand-node admit submit で投票を送信します(Command line)。rand_getAdmitted は、投票で承認されたものの未登録の鍵を一覧表示します。1 つのエポック境界で新たな重みになれるのは、アクティブな重みの 2,500 bps までです。Staking で手順を順に説明しています。独自のプライベートテストチェーンには、rand-node genesis で genesis を作成できます。

rand-node genesis --chain-id 88 \
    --validator a.key.json,1000,rand1<a's payout address> \
    --validator <hex public key of b>,1000,rand1<b's payout address> \
    --alloc rand1<address>=1000 \
    --epoch-blocks 1000 --faucet --fri-profile production \
    --out genesis.json

また、scripts/local-testnet.sh は、1 台のマシン上で 2 つの validator を、RPC を 8545 と 8546 にして実行します。追加のフラグがなければ、genesis には hc_auth も gas セクションもメモもありません。chain 20 は、これに加えて --hardening-v6 --bundle-guest v3 --auth-guest --gas-price 100 --byte-price 800 --bundle-gas-limit 20479 --gas-dynamic 10485760,262144,1250 --max-gas-price 10000 --max-byte-price 80000 --gas-byte-load paying --envelope-bytes 1860 --testnet --binding-domain 1 --proof-window-blocks 1024 --program-state-cell-fee 10000000 を付けて作成されました(chain 18 と 19 では --envelope-bytes までのフラグでした)。その bridge セクションと staking セクション、および consensus_domain は、作成スクリプトが組み込みました。独自に新しいチェーンを作る場合は --binding-domain 1 を渡してください。v0.6.8 のウォレットは、14 から 19 の範囲外のすべてのチェーン ID で、genesis にバインドされた形式の証明を行います。

Deploying on a server

リポジトリの deploy/ ディレクトリには、フリートが使用するスクリプトがあります。deploy/push-to-vps.sh <ip> <letter> "<bootstraps>" [validator|observer] は Linux サーバーをプロビジョニングし(ソースを rsync し、ビルドし、/usr/local/bin/{rand-node,rand} をインストールし、genesis ハッシュをキーとする datadir を初期化し、rand-node の systemd サービスをインストールします)、deploy/rebuild-vps.sh <ip> は新しいコミットでリビルドし、データを保持したまま再起動します。注意点が 2 つあります。1 つ目は、プロビジョニングスクリプトが deploy/genesis.json から初期化することです。これは chain 20 のファイルではないため、testnet 用のノードは deploy/genesis-chain20.json(main 上にあります。above を参照)から手作業でセットアップします。2 つ目は、どちらのスクリプトも /root/fullnode を --delete 付きで rsync するため、そのツリー内に置いた鍵は次のリビルドで削除されることです。フリートと同様に、また v0.6.8 のプロビジョニングスクリプトが現在デフォルトで行っているように、鍵は /root/keys に置いてください(v0.6.7 では鍵が /root/fullnode/deploy/ の下に書き込まれていました)。サービスの管理は systemctl status rand-node と journalctl -u rand-node -f で行います。サーバーには build-essential clang cmake pkg-config libssl-dev と Rust ツールチェーンが必要です。1 vCPU・2 GB のサーバーではバイナリをビルドできないため、別の場所でビルドしてコピーしてください。サイズと手順は Running a validator and an aggregator にあります。

The explorer

randscan.org は validator E の隣で稼働し、chain 20 をインデックスします。その REST API と WebSocket フィードは、ノードなしでチェーンを読み取る最も簡単な方法です(Explorer API)。エクスプローラーはオープンソース(randprotocol/randscan)で、そのインデクサーに必要なのはノードの rand_* JSON-RPC と PostgreSQL データベースだけなので、自分のノードに対して実行できます。

fullnode のコミット c0878c3f(チェーン 21)に対して 2026-10-12 に最終確認しました。 コードとこのページが食い違う場合は、コードが正です。お知らせください。