イーサリアムにおけるオンチェーンスケーリングソリューションであるShardingのロードマップが決められ、最初のphaseにおける仕様もある程度かたまってきました。

そこで、当記事ではSharding Phase1.0における基本的な仕組みや解決していかなければ課題点などをお伝えしていきます。

シャーディングの概要はこちらの記事でも解説していますのでぜひ併せてご覧ください。

参考:シャーディングがイーサリアムのスケーラビリティ問題を解決する理由

 

Shardingとは

現在のイーサリアムでは、ネットワークに参加するひとつひとつのノードが全てのトランザクションを処理しています。これにより、ネットワーク全体で共通の状態(Global State)を共有できており、ブロックチェーンネットワークとして安全性に優れていることになります。

しかし、「ひとつひとつのノードがひとつひとつのトランザクションを処理しなければならない」という制限のせいで、ネットワークに参加するそれぞれノードの計算リソースがボトルネックになってしまっているのです。

イーサリアムでは、ネットワークの分散性を保つためにBlock Gas Limit(ブロックサイズ)定めて、「たくさんのノードがネットワークに参加できる環境」を提供していることになりますが、このことがスケーラビリティに大きな制限を与えてしまっているのです。

 

そこで、Shardingではそれぞれのノードが全てのトランザクションを処理しなくても済むようすることでイーサリアムをスケールさせていこうという技術になります。イメージ的にはネットワークのノードを複数のShardsにグループ分けして、それぞれのShardsが独立しトランザクションを並列処理していくことになります。

これにより、従来では「ひとつのノードが全てのトランザクションを処理しなければならない」という状況から「ひとつのノードは自身の担当分のトランザクションのみを処理していけばいい」という状況に変えることができるのです。このような状況になれば、ひとつのノードの負担は減りますがネットワーク全体のキャパシティーは増加することになります。

 

さらに、このようにShardingが実装されるとネットワーク全体で共有されていたGlobal Stateから複数のSub Stateが登場することになります。なぜなら、それぞれのShardsが独立して特定のトランザクション群を処理しているので、それぞれのShardsの状態は異なってくるからです。

すると、絶対的に安全であったGlobal Stateからセキュリティ的に安全でないSub Stateが現れてくると予想できます。また、ブロックチェーンネットワーク間のトラストレスなコミュニケーションの実現が難しい現状を考えると、Shards間でのコミュニケーションもかなり困難であることが予想されます。

Shardingではこのようなセキュリティ的な問題点に対してどのように対処しつつ、イーサリアムをスケールさせていこうとしているのでしょうか。今回はその原型であるPhase1.0の仕様について見ていきます。

 

Sharding Phase1の内容

Shardingのロードマップでは、Phase1 では以下のように示されています。

Phase 1: Basic sharding without EVM

  • Blob shard without transactions
  • Proposers
  • Proposal commitments
  • Collation availability challenges

 

まず、phase1ではシャーディングの基本的な構造を成立させることにフォーカスしていきます。そのためEVMの実装もなくし、できるだけシンプルな形で行われます。(ただし現在、Phase1.1のスペックが考えられているので仕組みが変更する可能性が高いです。)

イメージ的にはスマートコントラクトを介してPoSのサイドチェーンを作るような形です。シャード間のコミュニケーションも後のphaseで実装される予定となっています。

また、メインネットワークとシャーディングネットワークはデータ可用性問題が解決するphase5まで分離されています。

 

シャーディングにおける3者の役目

シャーディング

 

shardingでは上図のように参加ユーザーによって3つの役割が存在します。まず、ユーザーによって送信されたトランザクションをプロポーザーと呼ばれる主体が回収し、collationsと呼ばれるブロックチェーンのブロックに似たようなデータ構造を作成していきます。

collationsは以下のようにshard_idを含めて、そのシャード特有のcollationであることが保証されています。以下collationsのヘッダー構造です。

[

shard_id: uint256

parent_hash: bytes32

chunk_root: bytes32

period: uint256

proposer_address: address

proposer_bid: uint256

proposer_signature: bytes

]

chunk_rootとは、シャードのトランザクション(blob)をシリアライズしバイナリマークル木構造でまとめたときのマークルルートとなります。

proposer_bidとは、プロポーザーからコレーターへの報酬金(手数料)です。

 

ユーザーが送信したトランザクションをこのcollationの構造にまとめるのがプロポーザーの役割です。

しかし、プロポーザーはこのトランザクションに不正がないかのチェックは行いません。通常のPoWにおけるマイナーであればトランザクションをブロック構造にまとめてデータ可用性まで検証しますが、シャーディングにおけるプロポーザーはトランザクションをまとめるだけでいいのです。

このCollationの検証はコレーター(Collators)と呼ばれる検証を専門に行う者によって行われます。コレーターはプロポーザーから提示されたcollationsに対して、不正がないかチェックを行います。そして、もし不正がなければそのcollationヘッダーを後述するShardingを管理するスマートコントラクトに送ることで、メインチェーンにコミットします。

 

このような3者の流れで特徴的なのがユーザーからプロポーザーへ、そしてプロポーザーからコレーターにお金が流れていくことです。ユーザーは通常のブロックチェーンと同様に高い手数料を支払うほどそのトランザクションが早くプロポーザーに選ばれ、Collationsに含めてもらうことができます。

そして、プロポーザーもコレーターに支払う手数料が高いほど自身のCollationsを選んでもらうことができるのです。なので、経済合理的にコレーターが動くとすると最も手数料が高いプロポーザーのCollationsを検証することになります。

 

shardingのセキュリティ

shardingにおいてさまざまなセキュリティ的課題点があげられますが、まず問題となるのが上述のコレーターが不正な検証を行う可能性があることです。例えば、プロポーザーと連携して自身に有利なトランザクションを含むCollationsを作りメインチェーンにコミットすることなどがあげられます。

このような不正を防ぐために主に以下の3つの対策がとられています。

  • コレーターになるためにはあらかじめ資金をデポジットしておく必要がある
  • シャードごとのコレーターは定期的にシャッフルされる
  • コレーターはシャードのCollationチェーンをフォークできる

 

まず、コレーターが資金をデポジットしておくことで何か不正をしたときはそのデポジットが没収されるような仕組みを導入しています。また、コレーターはある特定のシャードでずっと検証作業を行うことはできず、定期的にシャード間でバリデーターのシャッフルが行われます。phase1ではメインチェーンの5ブロックごとにバリデーターは新しいシャードにうつることになります。

これにより、プロトコル内でランダムにコレーターをシャードに割り当てることでBribing Attackなどのプロトコル外で賄賂を渡して連携するような攻撃モデルに対しても安全性を高めているのです。コレーターは自身で検証するシャードを選ぶことができないこともセキュリティを高めていることになります。

さらに、コレーターはシャードにおけるCollationsチェーンをフォークさせることができます。例えば、もし前回のcollationsが不正であると判断したら前々回のcollationからフォークして正当なcollationsを追加することができます。

 

プロポーザーとコレーターに分けている理由

それでは、なぜわざわざCollationを作成する作業とCollationを検証する作業の二手に分けているのでしょうか。これはコレーターの負担を減らすことが大きな理由です。コレーターは上述したようにランダムにシャードへ振り分けられます。(正確にはデポジットした資金量に基いてシャッフルが行われます。これはシャードごとにセキュリティ的な差がでないようにするためです。)

もし、これらがひとつの主体によって行われていると、コレーターはシャッフルされるごとに特定のシャードの全てのstateを再同期しなくてはいけなくなります。

一方、プロポーザーとコレーターの2つの主体に分かれていれば、コレーターは(phase2以降で実装される)シャードのstateを計算することなくプロポーザーから提示されたcollationを検証するだけでOKになります。このようなスムーズなシャッフルを可能にすることで、シャッフル期間を短くすることができ、攻撃者によるbribing攻撃(プロトコル外での賄賂等による結託)の余地を小さくする効果があるのです。

 

さらに、Phase 3からはこのプロポーザーとコレーターに加えてエグゼキューター(Executor)と呼ばれる主体も追加される予定です。Phase2においてEVM実装による状態遷移関数が導入されるので、エグゼキューターの役割はトランザクション処理に伴うstate計算を行い、state rootを提示することになります。

これにより、クライアントは実際にstate rootの算出を行わなくてもよくなるので、(stateless clientsの実装も併せて)シャードのフルノードを運営することなくライトクライアントのプロトコルが実装されることになるのです。

また、プロポーザーもエグゼキューターになることが想定されています。なぜなら、プロポーザーは(現在のマイナーのように)トランザクションに含まれる手数料を報酬として得ることができるので、stateを計算し、高いfeeを得られるトランザクションを優先的にcollationに含めていくことが経済合理的な行動になるからです。

 

Sharding Manager Contract の役目

ここまで解説したコレーターのシャッフルやCollation HeaderのメインチェーンへのコミットなどShardingに関するあらゆる管理はメインチェーンにデプロイされているSharding Manager Contract(SMC)によって行われます。

このSMCの状態がメインチェーンでのstateに反映されることで

SMCでは例えば、以下のようなデータを管理します。

  • notary_pool:参加中のコレーターのアドレス配列
  • availability_challenges:コレーターに対してチャレンジできるか
  • notary_registry:コレーターのアドレスをkeyとして、コレーターのIDなどの情報
  • proposer_registry:プロポーザーのアドレスをkeyとして、デポジット額などの情報

 

また、SMCのaddHeader関数によってある特定のシャードで追加されたcollationのヘッダーがオンチェーンで検証されることになります。

 

Sharding phase1の具体的な流れ

ここまでのまとめとして、phase1の具体的な流れを見ていきましょう。これは、go langでシャーディングの実装を進めているPrysatic Labsのひとつの実装案になります。

  1. コレーターSMCに100ETHデポジットする
  2. コレーターがメインチェーンのノードと通信し、ある一定の期間ごとに特定のシャードに割り当てられる
  3. プロポーザーがmemプールにあるトランザクションデータをシリアライズしcollationのボディーを作る
  4. コレーターが高い手数料を含むcollationに対して署名コミットメントをブロードキャストする(プロポーザーのリスクを低減させるため)
  5. プロポーザーがcollationボディーをコレーターにブロードキャスト
  6. もしコレーターの反応がない場合はプロポーザーがチャレンジし、コレーターのデポジットを没収
  7. コレーターは直近25個のcollationチェーンの正当性をチェックし、どのcollationからチェーンを伸ばしていくか決める。(SMCを介してcollationヘッダーを追加する)
  8. 次のピリオドに移り、SMCを介して新たなコレーターが決められる。また、コレーターをやめたい場合はデポジットを引き出せる。

 

セキュリティ的な課題点

windbackが必要

windbackとはセキュリティのためにcollationヘッダーを加える前にコレーターが直近25個くらいのcollationボディーをダウンロードし検証しなければならないことです。

上述したようにコレーターは頻繁にシャッフルされる予定で、このような検証が必要なことはスケーラビリティに反してしまいます。

具体的にはwindbackではcollationのデータ可用性(data availability)と正当性(validity)のチェックを行います。

 

データ可用性問題

データ可用性問題とは、ユーザーが全てのデータにアクセスすることができないことでfroud proof(不正の証明)や検証作業が正しく行うことができないことです。

例えば、ブロック生成者がトランザクションデータの一部、あるいは全てを隠してしまうことでユーザーから不正が主張されたとしても特にライトクライアントからはその主張が正当なのか判断できないことになります。

シャーディング

(source: A note on data availability and erasure coding)

例えば、上図のCase1ではブロック生成者に悪意があり、データの一部を隠してT2で他のユーザーが警告をしています。また、Case2では検証者に悪意があり、正しいデータに対してT2で警告を行なっています。

この場合、リアルタイムで全てのデータにアクセスすることができないユーザーからはこれら2つのパターンはログ情報としてどちらも同じであり区別することができないのです。また、このようなデータ可用性の問題はshardingだけでなくplasmaでも大きな問題となりえます。

 

シャード間コミュニケーション

シャード間のコミュニケーションはphase1では実装されず、phase4で主な実装が行われる予定です。シャード間のコミュニケーションはstateの送信ではなく、ログ情報であるreceiptによって行われます。

シャード間コミュニケーションでまず問題になるのが、異なるシャードで連携すべきトランザクションに対しての処理になります。例えば、train and hotel problemと呼ばれる問題では、シャード1で電車の予約をするためのトランザクション処理をして、シャード2でホテルの予約をするためのトランザクション処理をするとします。

この旅行予約のとき、どちらか一方の予約ができなければ両方の予約をやめるべきであり、両方の予約ができて初めて旅行の予約が完了します。つまり、このような状況において、「どちらも予約できるか」あるいは「どちらも予約しないか」の二択になります。どちらか片方の予約だけして、もう一方の予約はしない、という選択肢はありません。

 

このようなシャード間での確認(confirmation)を伴うコミュニケーションは現状難しく、まず考えられる解決法としては一定の時間を設けてその時間内に一方のシャードのメッセージがもう一方のシャードに「正しいメッセージ」として送られることを定める方法です。ただし、この場合「時間内にやりとりが完了しなければならない」という新たなセキュリティ基準が必要になってしまうことになります。

なので、まずphase2でSharding Manager Contract自体が複数のシャードに対して非同期にメッセージをコールするという方法が一時的な方法としてとられる予定です。

 

ここまでが現状シャーディングのphase1.0で考えられている仕様であり、現在spec1.1の議論が進められていることになります。spec1.0ではproposers/collatorsと分けていたのに対し、spec1.1ではproposers/notariesという主体に分けられる予定です。