スパインチェーン
ZooBC のすべてのノードは 2 つのチェーンを保持しています。メインチェーンは 15 秒ごとにブロックを作り、トランザクションを運びます。その横で動いているのがスパインです。mainnet では 1 日に 1 ブロックで、トランザクションはまったく運びません。スパインブロックは、レジストリ全体が保証するもの、すなわちメインチェーンのチェックポイント、加わったり離れたりしたノード鍵、最新のスナップショットのマニフェストを記録し、席の 3 分の 2 の署名を必要とします。そのためスパインは、ファイナリティのアンカーであり、すべての新しいノードの出発点です。
スパインブロックが保持するもの
- チェックポイント。 各スパインブロックは、確定したと言えるほど深いメインチェーンの参照ブロックを指定します。それはスパインブロックが作られた時点でメインチェーンの先端から 760 ブロック(3 時間 10 分)下にあり、直前のスパインブロックの参照より低くなることはありません。スパインブロックはそのブロックのマークルルートを写し、そのペイロードハッシュは参照ブロック自身のハッシュと累積難易度を確定させるため、チェックポイントは高さだけでなく、ちょうど 1 つのブロックを固定します。
- 公開鍵の変更。 直前のスパインブロック以降にレジストリに加わった、またはレジストリから削除されたノード鍵です。
- スナップショットのマニフェスト。 メインチェーンの状態の最近の各スナップショットについて、ファイル全体のハッシュ、すべてのチャンクのハッシュ、参照の高さ、有効期限、メインチェーンのジェネシスハッシュです(スナップショットとファストシンク を参照)。
スパインは spine_smithing_period ごとに 1 ブロックを作ります。mainnet と testnet では 86,400 秒、つまり 1 日に 1 ブロックで、devnet では 3,600 秒、つまり 1 時間に 1 ブロックです。devnet ではチェックポイントの深さは 80 ブロック(20 分)です。
席の 3 分の 2 による共同署名
スパインブロックは集約署名を持っています。4 バイトの件数に続き、署名者ごとに 32 バイトのノード鍵と 64 バイトの Ed25519 署名が並び、いずれも同じ 204 バイトのヘッダーに対する署名です。ブロックのハッシュは、ヘッダーのバイト列と署名フィールド全体の SHA3-256 です。
必要な署名の数は次のとおりです。
required = max(spine_min_signatures, ceil(n × 67 / 100))
ここで n は署名者リストの大きさです。席が 11 なら 11 × 67 / 100 = 7.37 で、切り上げて 8 です。切り上げは意図的です。7 では 11 の 3 分の 2 に満たないからです。
スパインは、一時停止中かどうかにかかわらず、署名者リストのすべての席を数えます。一時停止中の席も数えられる唯一の 3 分の 2 の集計であり、そのためチェックポイントは常にすべての席の 3 分の 2 を代表します(3 分の 2 ルール を参照)。
あまりに多くの席が失われてスパインが停滞した場合、基準は一段階緩みます。スパインブロックが保存されないまま 3 スパイン期間(mainnet では 3 日)が経過すると、過半数、つまり 11 のうち 6 で足りるようになります。どちらの基準も spine_min_signatures を下回ることはできず、これはどのチェーンでも 5 です。11 の署名すべてを求めると、1 つの席が欠けただけでスパインが止まってしまいます。
署名者は署名する前に確認する
席が盲目的に署名することは決してありません。提案に共同署名する前に、各署名者は次のことを確認します。
- 鍵の変更が、同じ範囲における自分自身のレジストリの変更と等しいこと
- 自分のチェーンのすべてのマニフェストが、ハッシュの 1 つひとつまで自分自身のスナップショットと等しいこと。スナップショットを持たない署名者は棄権します。
- 参照ブロックが十分に深く、後戻りしていないこと
- そのスパインの高さで、異なるブロックにすでに共同署名していないこと
ノードはスパインブロックを保存するとき、生成者の抽選とブロックの難易度とともに、内容を改めて確認します。
誰が、いつ提案するか
スパインの生成者は署名者リストから抽選されます。インデックス LE64(SHA3-256(seed ‖ "spine" ‖ round)) mod n の署名者で、seed は直前のスパインブロックの参照の高さにあるメインブロックのシードなので、すべてのバリデーターがこの抽選を再現できます。mainnet では、スパインのラウンドは 100 秒、作成枠は 300 秒、許容差は 150 秒です。署名者は、60 秒の収集時間枠より古い提案を拒否します。直前のスパインブロックに期間を加え、許容差を引いた時刻より早く届いたスパインブロックは拒否されます。
スパインブロックが空になることはありません。競合するスパインの間では、署名の多い方が勝ちます。ノードは何かをロールバックする前に競合するスパインの重みを量り、自分のスパインを リリースピン より下にロールバックすることは決してなく、もう一方のスパインの適用に失敗した場合は自分のスパインを元に戻します。
スパインの用途
- ファイナリティ。 どのノードも、最後に保存されたスパインのチェックポイントより下でメインチェーンを再編成しません(ファイナリティとロールバック を参照)。
- ファストシンク。 新しいノードはまずスパインを同期します。そのマニフェストがどのスナップショットを取得すべきかを示し、その鍵の変更がどのノード鍵を信頼すべきかを示します(スナップショットとファストシンク を参照)。
- アーカイブ。 ブロック 0 以降のすべてのスナップショットは、すべてのノードではなく分散ストレージが保持するため、誰でもスパインを過去の任意のスナップショットまで遡り、その時点の状態を再構築できます(アーカイブと過去の読み取り を参照)。
スパインは ZooBC Foundation ではなくすべてのノードが保持しており、その上で何かが取引されることはありません。