基於數據的EIP-7907分析

本文為機器翻譯
展示原文

以下報告旨在收集數據,希望這些數據能夠幫助 ACD 就 EIP-7907 做出決定。
此外,這有望建立一種新的方法,即用盡可能多的數據來支持 EIP 或提案,這肯定有助於在確定分支範圍時做出更好、更明智的決策。

我要感謝@rjl493456442提交的 PR,他在 Geth 中添加了相關指標,並在基準測試數據收集過程中提供了極大的幫助和建議。我希望最終能將這些指標標準化,以便在所有客戶端中通用,方便我們輕鬆比較和收集數據,從而為重新定價和擴展規模的決策提供依據。


相關問題:** EIP-7907
日期: 2026年1月13日
基準測試環境: Geth(開發模式),數據庫規模與主網相同(約 2400 萬個區塊),內部緩存已禁用。
測試配置:每個區塊約 18,106 次 EXTCODESIZE 操作(所有字節碼合約均不同),約 50M gas
硬件: WD Black SN850X NVMe (8TB)


執行摘要

本報告分析了在禁用 Geth 內部代碼緩存的情況下,讀取不同字節碼大小(0.5KB 至 64KB)合約時EXTCODESIZE操作碼的性能。這代表了最壞情況下的攻擊場景,攻擊者部署數千個不同的合約來強制執行冷磁盤讀取。

該迭代還具有最低的開銷,從而避免了CREATE2確定性地址生成的問題。
更多相關信息請參見:

主要發現

尋找價值
代碼讀取時間範圍107毫秒 - 904毫秒(約18000次代碼讀取)
每次通話延遲範圍5.9微秒 - 49.9微秒
代碼讀取時間縮放增長8.5倍(0.5KB → 64KB)
64KB 數據塊執行時間約1006毫秒
代碼讀取佔塊時間的百分比51% (0.5KB) → 90% (64KB)
Geth 效率對比原始 NVMe 24-51%

EIP-7907 裁決

尺寸塊時間1秒預算的百分比判決
24KB(當前) 535毫秒54%安全的
32KB 685毫秒69%安全的
64KB 1006毫秒約100%在60M氣體條件下可行
128KB+預計1.5秒以上100%以上可能需要重新調整天然氣價格。在 BALs 和 ePBS 之後,我們需要更多數據。

建議:將新的最大合約大小設定為 64KB。超過 64KB 則需要在 BAL 和 ePBS 的優化功能部署到所有客戶端後重新收集數據。
如果在上述數據收集之後需要重新定價,則此類定價還需要能夠對其他客戶進行基準測試,並參考其他EXTCODE*操作碼。


1. 方法論與基準測試設置

1.1 測試環境

範圍價值
Geth 版本v1.16.8-不穩定版(包含大量修改)
數據庫主網已同步(約2400萬個區塊)
Geth 緩存已禁用(強制磁盤讀取)
合同規模測試0.5、1、2、5、10、24、32、64 KB
EXTCODESIZE 操作每塊約 18,106 個
每塊氣體約5000萬
已部署合同每種規模的合同超過 18,100 份。
每個尺寸的迭代次數8
硬件WD Black SN850X NVMe 8TB

1.2 攻擊場景設計

此基準測試代表了針對EXTCODESIZE最壞情況攻擊

  • 每個規模部署超過 18,100 個獨特的合約(導致代碼緩存未命中)
  • 每個區塊都會從所有唯一合約中讀取字節碼,且讀取次數不得少於一次。
  • 代碼緩存命中率:<2%(實際上已禁用)
  • 基準測試運行之間清除操作系統頁面緩存

1.3 原始磁盤基線 (fio)

為了確定理論上的最大性能,我們測量了NVMe的原始性能:

塊大小IOPS吞吐量平均延遲
512B 337K 172 MB/s 95 微秒
1KB 320K 328 MB/s 100 微秒
4KB 272K 1.1 GB/s 117 微秒
24KB 171K 4.2 GB/s 185 微秒
32KB 155K 5.1 GB/s 204 微秒
64KB 85K 5.6 GB/s 366 微秒

2. 基準測試結果

2.1 代碼讀取時間與字節碼大小

7907_violin_code_read_time
7907_violin_code_read_time 1800×1050 91.5 KB
7907_code_read_vs_size
7907_code_read_vs_size 1500×900 55 KB

核心發現:當緩存無效時,代碼讀取時間與字節碼大小成正比。

尺寸代碼讀取時間(毫秒)增長量(相對於 0.5KB)
0.5KB 107毫秒1.0倍(基線)
1KB 135毫秒1.3倍
2KB 142毫秒1.3倍
5KB 145毫秒1.4倍
10KB 161毫秒1.5倍
24KB 428毫秒4.0x
32KB 584毫秒5.5倍
64KB 904毫秒8.5倍

關鍵發現:字節碼大小增長 128 倍時,代碼讀取時間增長 8.5 倍。這是亞線性增長(並非 1:1),但絕對時間影響非常顯著。

2.2 字節讀取時間與代碼讀取時間(相關性)

7907_code_read_vs_total_bytes
7907_code_read_vs_total_bytes 1500×900 76 KB

強正相關性(R² ≈ 0.96)證實,當緩存無效時,代碼讀取時間與讀取的總字節數成正比。

2.3 每次呼叫延遲

7907_每次調用延遲
每次調用延遲 7907,分辨率 1500×900,59.1 KB

每次調用延遲隨字節碼大小的增加而增加:

尺寸每次呼叫延遲生長
0.5KB 5.9 微秒1.0x
1KB 7.5 微秒1.3倍
10KB 8.9 微秒1.5倍
24KB 23.7 微秒4.0x
32KB 32.3 微秒5.5倍
64KB 49.9 微秒8.5倍

3. 執行時間細分

3.1 成分分析

7907_time_breakdown_stacked
7907_time_breakdown_stacked 1800×1050 69.2 KB

字節碼尺寸較大時,代碼讀取量成為主要因素

尺寸代碼讀取賬戶讀取EVM執行數據庫寫入其他全部的
0.5KB 107毫秒(51%) 54毫秒34毫秒12毫秒2毫秒209毫秒
1KB 135毫秒(57%) 53毫秒37毫秒12毫秒1毫秒238毫秒
10KB 161毫秒(59%) 53毫秒40毫秒12毫秒5毫秒271毫秒
24KB 428毫秒(80%) 44毫秒46毫秒15毫秒2毫秒535毫秒
32KB 584毫秒(85%) 38毫秒47毫秒13毫秒3毫秒685毫秒
64KB 904毫秒(90%) 38毫秒51毫秒12毫秒1毫秒1006毫秒

觀察:在 64KB 緩存大小下,代碼讀取消耗了 90% 的塊執行時間。這與熱緩存場景下代碼讀取僅佔 8-10% 的情況截然不同。


4. 時間塊預算分析(EIP-7907 重點)

4.1 時間與預算目標

7907_block_time_budget
7907_block_time_budget 1500×900 60.4 KB

使用 1 秒作為區塊執行目標:

尺寸塊時間1秒預算的百分比地位
0.5KB 209毫秒21%遠低於預算
1KB 238毫秒24%遠低於預算
2KB 248毫秒25%遠低於預算
5KB 252毫秒25%遠低於預算
10KB 271毫秒27%遠低於預算
24KB 535毫秒54%預算內
32KB 685毫秒69%預算內
64KB 1006毫秒約100%極限

結論:在6000萬gas區塊的最壞攻擊條件下,64KB合約是可行的。約1秒的執行時間雖然接近預算極限,但尚可接受。需要注意的是,考慮到ePBS和BAL很可能在不久的將來改變我們對安全預算的定義,這個極限相當保守。

4.2 天然氣處理率(定價錯誤分析)

7907_mgas_vs_size
7907_mgas_vs_size 1500×900 64.3 KB
尺寸燃氣使用塊時間兆氣體/秒
0.5KB 4940萬209毫秒236
1KB 4940萬238毫秒208
10KB 4940萬271毫秒182
24KB 4940萬535毫秒92
32KB 4940萬685毫秒72
64KB 4940萬1006毫秒49

發現定價錯誤: gas 成本相同,但執行時間卻相差 5 倍(236 Mgas/s → 49 Mgas/s)。這表明,在最壞情況下,規模更大的合約會給驗證者帶來不成比例的更高成本。

對 128KB 以上文件的影響:超過 64KB 後,需要對 gas 模型進行調整——可能是一個基本成本加上一個與大小相關的組件。

請注意,這還是相當保守的估計。因為要“癱瘓”網絡或“嚴重影響慢速驗證者”,所需的設置數量將是 18000 個獨立合約的數百倍。這將帶來巨大的成本(我們無法重複使用這些合約,因為它們會在第一個區塊執行後被緩存)。


5. 原始磁盤基準(Geth 與 NVMe 效率對比)

5.1 效率比較

7907_geth_vs_nvme
7907_geth_vs_nvme 2100×900 64.7 KB
尺寸Geth IOPS原始 NVMe IOPS效率Geth 吞吐量原始 NVMe效率
0.5KB 171K 337K 51% 83 MB/s 172 MB/s 48%
1KB 142K 320K 44% 139 MB/s 328 MB/s 42%
24KB 43K 171K 25% 1.0 GB/s 4.2 GB/s 24%
32KB 31K 155K 20% 979 MB/s 5.1 GB/s 19%
64KB 2萬85K 24% 1.26 GB/s 5.6 GB/s 23%

觀察結果: Geth 僅能達到磁盤原始性能的 20% 至 51%。造成這種差距的原因可能是:

  • Pebble/LevelDB 開銷(索引遍歷、布隆過濾器)
  • 密鑰哈希和查找
  • 值反序列化

6. 與熱緩存場景的比較

6.1 緩存與非緩存性能比較

7907_cached_vs_uncached
7907_cached_vs_uncached 1800×900 64 KB
尺寸暖緩存冷緩存減速
0.5KB 5.3毫秒107毫秒21倍
1KB 4.4毫秒135毫秒31倍
2KB 4.5毫秒142毫秒32倍
5KB 4.6毫秒145毫秒31倍
10KB 4.7毫秒161毫秒34倍
24KB 4.8毫秒428毫秒89倍
32KB 4.9毫秒584毫秒119x
64KB 4.9毫秒904毫秒181倍

在正常操作情況下,基於熱緩存基準測試得出的“固定成本”結論仍然有效。冷緩存條件則需要極端攻擊場景(超過 18,000 個獨立合約)。


7. 對 EIP-7907 的影響及建議

7.1 研究結果總結

  1. 在攻擊條件下,代碼讀取時間隨代碼大小而增加(從 0.5KB 到 64KB 增加到 8.5 倍)。
  2. 64KB 的數據在 6000 萬個 gas 塊的情況下是可行的——最壞情況下執行時間約為 1 秒,在預算範圍內。
  3. 這代表了最糟糕的情況——部署和維護 18000 多個獨特的合約是不切實際的(每次要運行攻擊的區塊都需要一個新的合約集)。
  4. 正常運行不受影響——熱緩存場景下開銷約為 5 毫秒。
  5. Gas定價錯誤問題正受到攻擊(相同gas的執行時間差異可達5倍)

7.2 EIP-7907 建議

行動推薦
64KB限制繼續執行——在最壞情況下的攻擊下仍然可行。無需 EIP。
128KB+限制需要使用支氣管肺泡灌洗液 (BAL) 和電子磷酸鹽緩衝液 (ePBS) 進行重新測量。

看來我們可以“保持簡單”,在不改變協議本身的情況下,為智能合約開發者提供代碼大小限制方面的良好升級,除了 64kB 的限制和 initcode 大小的增加之外。

一旦 BAL 和 ePBS 達到更完善的狀態,我們將能夠利用數據更好地指導我們做出關於重新定價/直接進入 256kB 的良好決策。
但即使在最糟糕的情況下,這東西也並不需要重新定價,所以現在重新定價似乎沒有必要。

7.3 為什麼 64KB 是可以接受的

  1. 攻擊不切實際:部署超過 18000 個唯一的 64KB 合約需要:

    • 每個合約部署約需 1300 萬 gas(3.2 萬基礎 gas + 6.4 萬 gas × 200 gas/字節)
    • 僅設置階段就需要數百個模塊。
    • 維護攻擊面需要持續投入大量成本
  2. 阻塞時間在預算範圍內:即使最壞情況下約 1 秒,對於 6000 萬個 gas 塊來說也是可以接受的。

  3. 緩存實際有效性:主主網區塊會複用合約;代碼緩存命中率通常很高。

  4. 亞線性擴展:規模增長 128 倍所需時間僅為 8.5 倍,這表明攤銷仍然有效。


來源
免責聲明:以上內容僅為作者觀點,不代表Followin的任何立場,不構成與Followin相關的任何投資建議。
喜歡
收藏
評論