Ethereum Foundation Blogで公開された、先月アップグレードされたBerlin以前に存在した脅威に関する開示記事↓
脅威とは?
↑の記事で取り上げられている脅威というは、処理に時間のかかるトランザクションを作成することでDoS攻撃を可能にするというもの。似たような攻撃として、上海アタックと呼ばれる攻撃が実際に2016年に行われ、gethが一時的に使えなくなるといった事態が発生した。
DoS攻撃を可能にするのは、Ethereumで成長中のステートツリーを利用したもの。このツリーはMerkle Patricia Trieと呼ばれるデータ構造で管理されている。この仕組みやボトルネックについては以前書いた↓参照。
techmedia-think.hatenablog.com
2019年に公開されたBroken Metreという論文では、遺伝的アルゴリズムを使って、処理に時間のかかるトランザクションを発見しようとする研究をしている。この遺伝的アルゴリズムで作成されたコントラクトを実行して分析したところ、アルゴリズムはEVMのopcodeのうちGAS
とBALANCE
の組み合わせに絞って時間のかかるトランザクションを作成していることが判明した。
これらの研究を基に、調査されたDoSトランザクションに関する開示が↓
DoS攻撃用に考えられたエクスプロイトは、巨大なEthereumのステートツリーに対して存在しないアカウントのデータを照会するopcodeを繰り返し呼び出すという方法で、以下のようなopcodeの呼び出しで実現できる:
JUMPDEST:(ジャンプ先としてマーク) GAS:(利用可能なgas量をスタックにプッシュ) BALANCE:(指定したアカウントの残高を取得) POP:(スタック要素をポップ) PUSH:(ジャンプ先をプッシュ) JUMP:(ジャンプ)
GAS
で得られた適当な値をアドレスとして、その残高を取得するという操作をgasが尽きるまで繰り返すというもの。BALANCE
opcodeの部分は、他のEXTCODEHASH
やEXTCODESIZE
でもいい。
このようなアカウントをMerkle Patricia Trie内で検索する場合、ステートツリーのルートから最後の目的のリーフまで辿り着くのに8〜9個のハッシュのDBに対するルックアップ操作が行われる。またさらにLevelDBの階層に伴うオーバーヘッドも発生する。
1,000万gas分↑を実行するトランザクションを実行すると、400 gasのEXTCODEHASH
を使った場合で、
- Parityが90秒
- gethが70秒
かかるという結果が報告されてる。現状のEthereumのmainnetだとgas limitは1,500万なのでさらに時間がかかることになる。ブロックの生成間隔が15秒であることを考えると、このような処理時間のトランザクションが発生すると上海アタックの時と同様ネットワークは動作しなくなる。
これが今回報告された脅威の内容。
Berlinのアップグレード後は安全なのか?
↑のような攻撃を回避するための方法として、導入されたのが↓の2つ。
EIP-2929
プロトコルレベルの改修としてEIP-2929で、BALANCE
やEXTCODEHASH
、EXTCODESIZE
を含むステートへアクセスするopcodeのgasコストの引き上げる。EIPの詳細については、id:y_nakajo のGBEC動画参照↓
スナップショットの導入
Geth v1.10から導入されたスナップショット構造↓
techmedia-think.hatenablog.com
スナップショットは新しい同期モードSnap syncを可能にするために利用されるが、同期以外にも、Merkle Patricia Trieからステートを読み取るとディスク読み込みのコストが↑のように発生するけど、スナップショットに対してステートを読み取る場合、O(1)で直接アクセスできるようになる。これによりステートへのアクセスコストを劇的に削減できる。
Berlinのアップグレード後、現在のmainnetの上限1500万gasでは、スナップショットを使わない場合に2.5〜3秒かかるブロックを作成することができると推定されている。これは今後のステートの成長と伴にさらに長くなっていく。ただ、スナップショットを利用するとさらに高速に処理することもでき、現時点で↑のエクスプロイトが深刻な脅威になることはひとまずなくなったことから、今回このような開示がされたみたい。
gas代の値上げによる手数料の増加はユーザーにとっては負担増になるけど、こういった攻撃が実行されるとチェーンそのものが停止してしまうというリスクがあるので、この辺りのバランスを調整していくのがどのチェーンでも大変な部分かもね。