レッスン7 — Stateless Ethereum(ress と stateless-validator を並べて読む)
問い
今日のメインネットで Reth フルノードを動かすには ~3 TB のディスク。多くの開発者はそれを動かせない → バリデータ層では「誰でも検証できる」が静かに事実でなくなる。Paradigm の ress は 14 GB で同じ検証をする。MegaETH の stateless-validator は高 TPS L2 をコモディティハードウェアで再検証する。2 つの本番品質 Rust 実装が、興味深いすべてのレイヤで違う設計を選んでいる — その対比は何を教えるか?
原理(最小モデル)
- ステートレス = ワールド状態を持たずに検証. Witness(前ブロックの信頼済み stateRoot に対して、ブロックが触るスロットの値を暗号学的に証明する束)から状態を読む。
- Witness ソースの非対称性. ステートフルでない誰か(Reth フルノード / MegaETH sequencer)が witness を生成、ステートレス検証者は信頼ではなく 暗号学的に witness を stateRoot で検証する。
- ress = フルステートレス(state + bytecode). MPT 証明、メインネット、Reth ピアから RLPx で取得、~14 GB ディスク。
- stateless-validator = 部分ステートレス(state ステートレス、bytecode 別キャッシュ). SALT 証明(Banderwagon + IPA)、MegaETH、sequencer から JSON-RPC で取得、bytecode は
ContractCacheローカル永続化。 - 並列性の違い. ress = 1 ブロックずつ(CL ペーシング)/ stateless-validator = ブロック横断 embarrassingly parallel(各ブロックが独立 witness + pre-state root を持つ)。
- 複数実行エンジン. stateless-validator は revm + 形式 K-セマンティクスを両方サポート → コンセンサスバグの第二意見、TCB を小さく保つ。
具体例
ress(Paradigm):
- 対象: Ethereum メインネット
- ディスク: 14 GB
- Witness ソース: Reth フルノード(
--ress.enable)、専用 RLPx サブプロトコル - Witness フォーマット: MPT 証明(
AccountProof/StorageProof) - Bytecode: ピアから オンデマンド + キャッシュ
- 検証フロー: CL が
NewPayload→ ress が Reth ピアに witness + 不足 bytecode を要求 → メモリ上検証 →PayloadStatus返す - 本番ステータス: Holesky でバリデータ実走、Hive Cancun テスト 226/206 パス
stateless-validator(MegaETH):
- 対象: MegaETH(高 TPS L2、OP-Stack 系)
- Witness ソース: MegaETH sequencer の専用 RPC エンドポイント
- Witness フォーマット: SALT 証明(Banderwagon + IPA、~1 GB メモリで 30 億アイテム認証)
- Bytecode: 部分ステートレス — public RPC から取得 + 有界
ContractCache永続化 - 検証フロー: 3 ステージパイプライン(FETCH → PROCESS → ADVANCE)、複数ワーカーが異なるブロックを並列処理
- 実行エンジン: revm + 形式 K-セマンティクス(プラガブル)+ JIT は sequencer 側
- 信頼モデル: state 遷移検査、カノニカル性は
op-nodeが L1 + DA から導出(trust-minimized)
サイドバイサイド:
| 観点 | ress (Paradigm) | stateless-validator (MegaETH) |
|---|---|---|
| 対象チェーン | Ethereum メインネット (L1) | MegaETH (L2) |
| Witness フォーマット | MPT 証明 | SALT 証明 (Banderwagon + IPA) |
| Witness ソース | Reth ピア、ress RLPx サブプロトコル経由 | Sequencer、--witness-endpoint JSON-RPC 経由 |
| Bytecode 処理 | ピアからオンデマンド取得・キャッシュ | RPC からオンデマンド取得、ContractCache にキャッシュ |
| ステートレス度 | フル (state) | 部分 — state はステートレス、bytecode はそうでない |
| 実行エンジン | revm (単一) | revm と 形式 K-セマンティクス (プラガブル) |
| 並列性 | 1 ブロックずつ (CL ペーシング) | ブロック横断で embarrassingly parallel (N ワーカー) |
| カノニカル性 | コンセンサスクライアントを信頼 (Engine API) | op-node を信頼 (L1 + DA 導出) |
| ディスクフットプリント | ~14 GB | ContractCache + redb メタデータで有界 |
失敗例(誤解)
「ステートレスは小さいノードのための機能」— 間違い。検証者層の機能で、4 用途: ① L1 分散化(ラップトップで完全検証)+ ② L1 ガス上限拡張(state read のランダム I/O が天井を決めていた)+ ③ Optimistic L2 セキュリティ(fraud-proof 見張りが安く)+ ④ Native rollups(再実行可能な検証者は 3 TB 状態を抱えられない)。
「ピアから witness を受け取るのは信頼」— 間違い。暗号学的に witness を stateRoot に対して検証する。1 バイトでも改竄されれば検証失敗。信頼するのはピアではなく 手元の信頼済み stateRoot。
「ステートレス = 完全ステートレス」— 間違い。MegaETH は 部分ステートレス(state は witness、bytecode は別キャッシュ)。bytecode は state と性質が違う(滅多に変わらない、同じ 100 KB を毎ブロック送るのは無駄)→ 一度取って局所キャッシュが合理的。設計選択の自由度。
🛑 予測。 「ステートレス」ノードはフル状態を持たずにブロックを検証する。ブロックプロポーザーは普通のノードに送らないものを、ステートレスノードには何を送らないといけないか? その追加ペイロードは何と呼ばれる?(答え: ブロックが触る state 値とその MPT 証明 = witness。サイズは数百 KB - 数 MB / ブロック(典型)。フルノードは自分の DB から state を読むので witness は不要、ステートレスノードはこれが state アクセスの唯一の経路。)
ステップで組み立てる
Step 1: 「ステートレス」を 1 文で
ワールド状態を持たず、witness(前ブロック stateRoot に対する暗号証明束)から state を読んで検証 + 次の stateRoot を再導出。
Step 2: ステートレスの 4 用途
① L1 分散化、② ガス上限拡張、③ Optimistic L2 セキュリティ、④ Native rollups。
Step 3: 2 実装の差分軸 9 つ
対象 chain / Witness ソース / Witness フォーマット / Bytecode / ステートレス度 / 実行エンジン / 並列性 / カノニカル性 / ディスク。
Step 4: 設計対比の解釈
- bytecode 別キャッシュ(MegaETH): bytecode は滅多に変わらない + 毎 witness に含めるのは無駄 → 一度取って局所キャッシュ。L2 sequencer 集中型なので「単一 RPC からオンデマンド取得」が成立。
- 複数実行エンジン(MegaETH): revm のコンセンサスバグ → 全 Reth 系 chain のコンセンサスバグ。形式 K-セマンティクスは設計上違うバグ → 第二意見。小さな Trusted Computing Base 原則。
- embarrassingly parallel(MegaETH): 各ブロックが独立 witness + pre-state root → N ワーカーで並列、CL ペーシングに縛られない。
Step 5: 並べて読まないと見えないこと
ress 単独だと「witness は常に MPT」「ステートレス = フル」「実行エンジンは 1 つ」と思い込む。stateless-validator 単独だと「ステートレスには常にカスタム commitment」「L2 流の trust-minimized 導出パイプライン必須」と思い込む。対比が教えるのはダイヤルの自由度。
答え合わせ
- 「ピアから witness 信頼」が誤りである理由: stateRoot に対する MPT 証明として witness を暗号学的に検証する。1 バイト改竄で検証失敗 → 「信用する」ではなく「ハッシュ結果が手元の信頼済み 32 バイトと一致する」。
- MegaETH の bytecode 別取り扱い: bytecode は state と違って滅多に変わらない + ホット DeFi コントラクトは毎ブロック state 発信するが bytecode はデプロイ以来不変 → 毎 witness に含めるのは同じ 100 KB を再送 → ローカル
ContractCacheに取得 + キャッシュが合理的。 - MegaETH の複数実行エンジンが防ぐもの: revm 系クライアントを 1 つだけ動かしていると、revm の 1 つのインタプリタバグでチェーン分裂 / 凍結 + 第二意見得られず。形式 K-セマンティクスは数学的に違うバグなので、両者一致が大きな信頼度向上。小さな Trusted Computing Base の規律。
合格基準
- 「ステートレス」を witness 概念で定義できる。
- ステートレス 4 用途を即答できる。
- 9 観点の差分を ress / stateless-validator で表で書ける。
- bytecode 別キャッシュと複数実行エンジンの設計理由を説明できる。
- 「並べて読む」が単独読みより教える内容を 2 つ言える。
まとめ(3行)
- ステートレス = witness(stateRoot に対する暗号証明束)で state を読み、ワールド状態を持たずに検証 + 次の stateRoot を再導出。
- ress(フルステートレス、MPT 証明、メインネット)と stateless-validator(部分ステートレス、SALT 証明、L2、複数実行エンジン)の対比が設計の自由度を見せる。
- 「ステートレスは小さいノードの機能」ではなく、検証者層の機能 — 4 用途(L1 分散化 / ガス上限 / Optimistic L2 / Native rollups)すべてに効く。