FABRKNT
Inside Revm — EVM エンジンを読む
Revmの心臓部
レッスン 14 / 17·CONTENT22 分45 XP
コース
Inside Revm — EVM エンジンを読む
レッスンの役割
CONTENT
順序
14 / 17

レッスン13 — Revm 自身のテスト — state test / EOF / execution-spec

問い

インタープリター + 命令テーブル + Database トレイトは歩いた。Revm チームが「Revm が EVM を正しく実行する」をどう証明しているか? コンセンサスクリティカルなエンジン = バグ 1 つでチェーン分裂、別の基準で計られる。3 テスト面の役割と境界は?

原理(最小モデル)

  • 3 テスト面. State tests(ethereum/tests、複数クライアント横断、pre → tx → post)/ EOF tests(ethereum/tests/EOFTests、EOF コンテナ validation)/ execution-spec-tests(ethereum/execution-spec-tests、仕様から生成)。
  • State test の形. JSON 3 セクション = pre(実行前状態)/ transaction(適用)/ post(fork ごとに state-root + logs ハッシュ)。runner = pre 構築 → tx 実行 → post ハッシュ化 → 比較。
  • EOF test の形. バイトコードの validation 準拠、「validate される」or 「このエラーで reject される」アサーション、構造クリティカル(不正コンテナ accept / 有効 reject はチェーン分裂)。
  • execution-spec-tests の強み. Python フレームワークで spec-aware DSL で書く → 全 fork に対し具体的 state test 自動生成 → pass = 構造的に仕様と一致
  • 3 面の役割分担. State tests = 実行セマンティクス確定後、EOF tests = コンテナ validation(別クラスバグ)、execution-spec-tests = 仕様変更を最速で捕まえる(EIP draft 段階)。
  • Revm 消費者の教訓. ① pre → tx → post = EVM 実行の普遍形、② 他リファレンスへの differential(「自分は仕様ではないが一致」)= Building tier の Revm シミュレーション検証パターン、③ 生成テスト ≥ 手書き(仕様が権威時)。
  • Revm が state tests を走らせる必要性. Revm 埋め込み全クライアントは Revm の正しさを継承 = Revm のバグは全下流クライアントのバグ、エンジン層の規律。

具体例

State test JSON:

{
  "TestName": {
    "env": { "currentNumber": "...", "currentTimestamp": "...", "currentGasLimit": "..." },
    "pre": {
      "0xAlice": { "balance": "0x..", "nonce": "0x..", "code": "0x..", "storage": {} }
    },
    "transaction": {
      "data": ["0x..."],
      "gasLimit": ["0x..."],
      "to": "0xBob",
      "value": ["0x.."]
    },
    "post": {
      "Cancun": [{
        "hash":   "0x...post-state-trie-root...",
        "logs":   "0x...logs-bloom...",
        "indexes": { "data": 0, "gas": 0, "value": 0 }
      }]
    }
  }
}

EOF test:

{
  "EmptyContainer": {
    "code": "0x",
    "results": { "Cancun": { "exception": "EOFException.MISSING_HEADER" } }
  }
}

execution-spec-test:

@pytest.mark.valid_from("Cancun")
def test_my_opcode(state_test, fork):
    pre = { Address(0x1000): Account(code=Op.MY_NEW_OPCODE + Op.STOP) }
    tx = Transaction(to=Address(0x1000), gas_limit=100_000)
    post = { Address(0x1000): Account(storage={0: 1}) }
    state_test(env=Environment(), pre=pre, post=post, tx=tx)

3 面の捕まえタイミング:

捕まえタイミングクラス
execution-spec-testsEIP draft branch(活性化前)仕様変更 → 自動生成
State testsfork ロールアウト中確定挙動の正典
EOF tests別クラス(構造 validation)コンテナ形式

失敗例(誤解)

「3 テスト面は冗長」— 間違いコンセンサス正しさの空間を分割、execution-spec が仕様変更を最速で捕まえ、state tests が確定挙動を正典化、EOF tests がコンテナ validation を担当、各々別クラスのバグを捕まえる。

「Revm はライブラリだから state tests 走らせる必要なし」— 致命的Revm 埋め込み全クライアント(Reth / Hyperliquid / Tempo / Berachain)は Revm の正しさを継承 = Revm のバグは全下流クライアントのバグ = エンジン層の規律。

「手書きテストで十分」— 間違い(仕様が権威時)。execution-spec-tests = テストが仕様から生成 = pass = 構造的に仕様と一致、手書きテストが取り逃すバグを捕まえる。

ステップで組み立てる

Step 1: State tests の役割

JSON 3 セクション(pre / tx / post)+ runner(pre 構築 → tx → post ハッシュ比較)= 確定挙動の正典、複数クライアント横断。

Step 2: EOF tests の役割

バイトコード validation 準拠、構造クリティカル(不正コンテナ accept / 有効 reject はチェーン分裂)。

Step 3: execution-spec-tests の役割

Python フレームワーク + spec-aware DSL → 全 fork に具体 state test 自動生成 = pass = 仕様一致、最速で仕様変更を捕まえる。

Step 4: 3 面の役割分担

実行セマンティクス(State)+ コンテナ validation(EOF)+ 仕様変更最速(execution-spec)= 冗長ではなく分割

Step 5: Revm 消費者の教訓

pre → tx → post の普遍形 / differential パターン / 生成 ≥ 手書き。

Step 6: Revm が state tests 必須の理由

Revm 埋め込み全クライアントが正しさ継承 = エンジン層の規律。

答え合わせ

  • 3 テスト面が分割する空間: ① State tests = 実行セマンティクス確定後の正典挙動、② EOF tests = コンテナ validation(実行前のパース / validate、別クラスバグ)、③ execution-spec-tests = 仕様変更を最速で捕まえる(EIP draft 段階で CI が回す)。「ガスコスト変更」を例に: execution-spec が EIP merge 前に捕まえ、State tests が fork ロールアウト中に捕まえ、EOF tests は捕まえない(構造ではない)。
  • execution-spec-tests が「pass = 仕様一致」を保証する根拠: テストが spec-aware DSL で書かれ仕様から自動生成 = テスト pass = 構造的に仕様と一致。手書きテストは「自分が書いたものとは一致」しか保証しない、仕様との乖離を捕まえられない。新 EIP(新 opcode / precompile / ガス規則変更)がカバレッジを得る方法。
  • Revm が state tests を走らせる必要性: Revm は ライブラリだが、埋め込み全クライアント(Reth / Hyperliquid / Tempo / Berachain)が Revm の正しさを継承 = Revm のバグは全下流クライアントのバグ = mainnet 起動前に互換性報告する必要 = エンジン層に住む規律。「ライブラリだから関係ない」が成立しない構造。

Expert への接続

このレッスンは revm 本体 の性質としての state-test 規律を扱う。Expert tier ではこれを systems 層に広げる 2 レッスンがある:

合格基準

  • 3 テスト面(State / EOF / execution-spec)の役割を即答できる。
  • State test JSON 3 セクション(pre / tx / post)を即答できる。
  • EOF test の構造クリティカル理由を 1 文で説明できる。
  • execution-spec-tests が「pass = 仕様一致」を保証する根拠を即答できる。
  • Revm 消費者の 3 教訓(pre→tx→post / differential / 生成 ≥ 手書き)を即答できる。
  • 「Revm が state tests を走らせる必要性」の根拠(埋め込み全クライアント継承)を 1 文で説明できる。

まとめ(3行)

  • 3 テスト面 = State tests(確定挙動の正典)+ EOF tests(コンテナ validation)+ execution-spec-tests(仕様変更最速、自動生成)= 冗長でなく分割。
  • 「pass = 仕様一致」を保証するのは execution-spec-tests(DSL → 仕様から自動生成)、手書きテストは「自分が書いたものとは一致」しか保証しない、新 EIP カバレッジの正規ルート。
  • Revm 埋め込み全クライアント(Reth / Hyperliquid / Tempo / Berachain)が正しさ継承 = Revm のバグは全下流バグ = state tests 走らせるのはエンジン層の規律、次は並列実行(block-stm)。