BIP: 54
Layer: Consensus (soft fork)
Title: Consensus Cleanup
Authors: Antoine Poinsot <mail@antoinep.com>
Matt Corallo <bips@bluematt.me>
Status: Complete
Type: Specification
Assigned: 2025-04-11
License: CC0-1.0
概要
本文書は、タイムワープ攻撃を修正し、最悪ケースのブロック検証時間を削減し、マークルツリーの脆弱性を防ぎ、BIP30 (https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki)検証を伴わずに重複トランザクションを回避するための、新しいコンセンサスルールを提案する。
動機
本提案は、ビットコインプロトコルにおける、長らく知られてきた複数の脆弱性と弱点に対処するものである。これらの修正をまとめてバンドルすることで、ビットコインのソフトフォークをデプロイする際に生じる固定コストを分散する。
タイムワープバグ (https://bitcoin.stackexchange.com/questions/75831/what-is-time-warp-attack-and-how-does-it-work-in-general/75834#75834)は、過半数のハッシュレートを持つ攻撃者がマイニング難易度を任意に引き下げ、それによってブロック生成率を任意に引き上げることを可能にする。最悪の場合、攻撃者は攻撃開始から 38日以内に難易度を最低値まで引き下げることができる。51%攻撃者に力を与えるだけでなく、このバグの存在はマイナーのインセンティブについて推論することを難しくする。ブロック生成率を加速させることで、攻撃者は将来のマイナーからブロック補助金を奪い取り、利用可能なブロック容量を増加させることができる。ネットワークを致命的に傷つけることなくブロック生成率を大幅に増加させるために、この脆弱性を悪用することが、近視眼的なユーザーやマイナーの利益になる場合がある。
特別に細工されたブロックは処理コストが高くつく可能性があり、高性能デバイスでも検証に最大で数分 (https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/93)、低性能デバイスでは数時間を要することがある。ブロック検証時間が長いことは、コンセンサスルールを独立して完全検証するコストを増加させ、ユーザーにとって迷惑である。加えて、マイナーが競合相手を攻撃するために悪用し、倒錯したインセンティブや中央集権化圧力を生み出し、ネットワークセキュリティの低下につながる可能性がある。
ブロックのマークルルートを計算する際、非ウィットネスデータがちょうど 64 バイトのトランザクションは、ツリーの中間ノードとしても、ツリーの葉としても解釈できてしまう1。これにより、64 バイトのブロックトランザクションをあたかも内部ノードであるかのように偽装することで、SPV 検証者に対し、実際にはそのブロックに含まれていないトランザクションの包含証明を受け入れさせるよう仕向けることが可能になる。64 バイトのトランザクションを無効化することで、SPV 検証者の利用者や、その他のマークル証明の利用者に対し、既知の回避策2のいずれかに頼ることも、そもそも回避策が必要であると知ることさえも求めることなく、この脆弱性に対処する。
BIP34 (https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki)の有効化以降、明示的な BIP30 (https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki)検証はブロック高 1,983,7023まで不要である。BIP30 (https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki)検証を再開すると、ブロック検証のオーバーヘッドが不必要に増加し、(BIP182 (https://github.com/bitcoin/bips/pull/1923) Utreexo のような)代替のフルノード設計を妨げることになる。新しいコインベーストランザクションが初期の BIP34 (https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki)違反と異なることを強制することで、BIP30 (https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki)検証を永久に不要にすることが可能になる。
仕様
有効化後のすべてのブロックには、以下の新しいルールが適用される。
高さ N にあるブロックが与えられたとき:
N % 2016が 0 に等しい場合、そのブロックのタイムスタンプは、高さN-1のブロックのタイムスタンプの値からマイナス 7200 を引いた値以上でなければならない(TN ≥ TN−1 − 7200)。N % 2016が 2015 に等しい場合、そのブロックのタイムスタンプは、高さN-2015のブロックのタイムスタンプの値以上でなければならない(TN ≥ TN−2015)。
トランザクションの検証に使用されるスクリプト内の署名操作の数には上限が設けられる。これはコインベーストランザクションを除くブロック内のすべてのトランザクションに適用される4。トランザクションの各インプットについて、そのインプットの scriptSig および対応する前アウトプットの scriptPubKey(P2SH の redeemScript を含む)内にある CHECKSIG と CHECKMULTISIG の数を数える。トランザクションの全インプットにわたる合計が 2500 を厳密に超える場合、そのトランザクションは無効である。その計算方法は BIP16 (https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki#specification)と同様であり、scriptSig・scriptPubKey・P2SH の redeemScript を個別に評価する。
CHECKSIGとCHECKSIGVERIFYは、評価されるか否かにかかわらず、1回の署名操作として数える。OP_1からOP_16の直後に置かれたCHECKMULTISIGとCHECKMULTISIGVERIFYは、評価されるか否かにかかわらず、1回から 16回の署名操作として数える。- それ以外のすべての
CHECKMULTISIGとCHECKMULTISIGVERIFYは、評価されるか否かにかかわらず、20回の署名操作として数える。
ウィットネスを除いたシリアライズサイズがちょうど 64 バイトであるトランザクションは無効である。
コインベーストランザクションの nLockTime フィールドは、ブロック高からマイナス 1 した値に設定されなければならず5、その nSequence フィールドは 0xffffffff と等しくなってはならない。
論拠
難易度調整期間の最初と最後のブロックのタイムスタンプに対する制約は、タイムワープおよびマーチ=ザウィの脆弱性6を修正する。後者は主に理論上の懸念にとどまるが、修正のリスクは極めて低い。調整期間の長さがマイナスになったことは一度もなく、今後もそうあってはならないためである。前者は、難易度期間の最初のブロックのタイムスタンプが直前のブロックのそれより低くならないようにし、2時間の猶予期間を設けることで修正される。タイムワープ攻撃を修正する以前の提案 (https://github.com/TheBlueMatt/bips/blob/7f9670b643b7c943a0cc6d2197d3eabe661050c2/bip-XXXX.mediawiki)では、代わりに 10分の猶予期間が用いられており、この方式は testnet4 (https://github.com/bitcoin/bips/blob/master/bip-0094.mediawiki#time-warp-fix)で採用されている。攻撃下でのブロック生成率の悪化をわずかにしか悪化させないことから、慎重を期して本提案では 10分ではなく 2時間の猶予期間を用いる7。
一部のスクリプト操作や機能を無効化することで最悪ケースのブロック検証時間を削減する案が以前提案された (https://github.com/TheBlueMatt/bips/blob/7f9670b643b7c943a0cc6d2197d3eabe661050c2/bip-XXXX.mediawiki)が、没収(confiscation)への懸念から抵抗を受けた8。緩和策の没収リスク(たとえ理論上のものであっても)を最小化することと、システムの他のすべての利用者に課しうるコストを制限することの間には、微妙なバランスが必要とされる。この目的のため、実行されうる署名操作を制限することで、Script の利用における柔軟性を最大限に保ちながら、まさに有害な振る舞いだけを狙い撃ちする。この上限により、最悪ケースのブロック検証時間は 40分の 1 に削減され、攻撃の準備コストが大幅に増加し、マイナーにとって採算が合わなくなる9。2500 という上限値は、病的ではない標準的なトランザクションを無効にしない範囲で最も厳しい値として選ばれた10。
64 バイトのトランザクションが持てる scriptPubKey は、誰でも資金を使用できるものか、資金を焼却するもののいずれかに限られる。これらは 2019年以降非標準となっており、2016年以降一度も使われていない。64 バイトのトランザクションを無効化する以外にも、これまでいくつかの代替案が提案されてきた。マークル証明の利用者にとっての改善は、有効なウィットネス除去済みトランザクションサイズの集合に不連続点を導入するに値するほど大きくはないと考える者もいる(議論はこちら (https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/41))。他には、代わりにマークルツリーの深さをヘッダーの version フィールドにコミットすることを提案する者や11、あるいはビットコイントランザクションの有効なシリアライズに対応するマークルツリーノードそのものを無効化することを提案する者もいる12。これらの選択肢は、利用可能な回避策2の一部をより導入しやすくする。著者らは、根本原因に対処する形で 64 バイトのトランザクションを無効化することが望ましいと考える。これにより、64 バイト以外のトランザクションのマークル証明に依存する利用者について、回避策を必要とすることなく脆弱性を修正できる。
トランザクションの nLockTime フィールドは、ブロック高を格納する自然な場所であり、コインベーストランザクションでは現在未使用である。これを用いて、新しいコインベーストランザクションが初期の BIP34 (https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki)違反と異なることを強制することで、アプリケーションは Script を解析することなくブロック高を復元できるようになる。既存のタイムロック機構を活用することで、このチェックは自己完結的になる。同じコインベーストランザクションが過去のブロックで有効であったことはあり得ないためである13。これにより、Consensus Cleanup の有効化後は BIP30 (https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki)チェックを完全に省略できるようになり、これは BIP34 (https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki)の有効化状況にかかわらず、推論とクライアント実装の両方を単純化する14。ある人物は、ASIC コントローラーがマイニング運用のボトルネックとなった場合、nLockTime フィールドが理想的なエクストラナンスになってしまうという懸念を提起した (https://groups.google.com/g/bitcoinminingdev/c/jlqlNHHNSNk)。他の者は、必要になった場合は代わりにダミーアウトプットを用いることで同じ利点を得られると反論した (https://groups.google.com/g/bitcoinminingdev/c/jlqlNHHNSNk)。著者らは、コインベーストランザクションを区別するために nLockTime を用いる利点は、ASIC コントローラーによるエクストラナンスのローリングに利用できなくなるという理論上のコストを上回ると考えている (https://gnusha.org/pi/bitcoindev/UsKuvCXXhSAnNVx5a0K2UfP3srAr3slW9mcOjtYk9LnolaOXfWrW9jpqbxsQQPkyQuZogkhz2Hbfwii2VsTm79vRDpgKduxk35hpBu_t7Do=@protonmail.com/)。
後方互換性
本提案はブロック検証ルールを厳格化するのみである。すなわち、本 BIP で提案されるルールの下で有効だが、既存のビットコインのコンセンサスルールの下では無効となるブロックは存在しない。したがって、これらの変更は未アップグレードのノードソフトウェアと後方互換性がある。とはいえ、著者らは、すべてのコンセンサスルールを完全に検証できるよう、ノード運用者にアップグレードを強く推奨する。
マイナー向けの前方互換性
Bitcoin Core バージョン 29.0 (https://bitcoincore.org/en/releases/29.0)以降は、本 BIP で導入されるタイムスタンプ制約に違反するブロックテンプレートを生成しない。本提案で用いられる猶予期間により極めて起こりにくいことではあるが、マイナーは自身のブロックが常に本提案に準拠して有効になるよう、getblocktemplate の結果の curtime または mintime フィールドを自身のブロックのタイムスタンプに用いるべきである。これは新しい要件ではないことに注意されたい。getblocktemplate の結果の mintime フィールドより低いタイムスタンプを用いることは、既に無効なブロックの生成につながる。
Bitcoin Core バージョン 30.0 (https://bitcoincore.org/en/releases/30.0)以降は、本 BIP で導入される署名操作の上限に違反するトランザクションを含むブロックテンプレートを生成しない。
Bitcoin Core バージョン 0.16.1 (https://bitcoincore.org/en/releases/0.16.1)以降は、ウィットネス除去済みシリアライズサイズがちょうど 64 バイトであるトランザクションをリレーすることも、それを含むブロックテンプレートを生成することもない。
コインベーストランザクションは通常、マイニングプールのソフトウェアによって作成される。著者らの知る限り、そうしたソフトウェア向けに広く使われているオープンソースのリファレンス実装は存在しない。マイニングプールには、本 BIP で提案される変更と前方互換性のあるコインベーストランザクションを作成するよう、ソフトウェアを更新することを推奨する。
リファレンス実装
Bitcoin Core 向けの BIP54 の実装はこちら (https://github.com/bitcoin/bitcoin/pull/35793)で入手できる。
テストベクター
本 BIP で導入されるすべての緩和策について、文書化されたテストベクターはこちらで入手できる。
謝辞
本文書は、マット・コラロによる以前の提案 (https://github.com/TheBlueMatt/bips/blob/7f9670b643b7c943a0cc6d2197d3eabe661050c2/bip-XXXX.mediawiki)を土台としている。
著者らは、これらの各バグに対する最も適切な緩和策を研究する取り組みに関わったすべての人々に感謝したい。とりわけ、本提案への直接的な貢献について、アンソニー・タウンズとスヨルス・プロヴォーストに、そして提案された緩和策の分析に用いるデータを提供してくれたことについて、0xb10c とブライアン・グロールに感謝したい。新しいトランザクションサイズルールに対する過去の違反事例を掘り起こし、その一部が本 BIP のテストベクターに再利用されているクリス・スチュワートにも感謝する。
著作権
本文書はクリエイティブ・コモンズ CC0 1.0 ユニバーサル・ライセンスの下でライセンスされる。
変更履歴
- 1.0.0(2026-05-22):
- 本 BIP の計画された作業を完了。
Footnotes
-
逆に、ツリーのある階層の内部ノードを、あたかも実際のブロックトランザクションであるかのように偽装することも、フルノード実装にとって別の複雑性の原因であり、過去にコンセンサスバグを引き起こしたことがある。たとえば、Bitcoin Core の 0.13.0 から 0.13.2 までのバージョンは、この攻撃に対して脆弱なキャッシュ機構を実装していた。詳細な説明については、スハス・ダフタールによるこの解説記事 (
https://gnusha.org/pi/bitcoindev/CAFp6fsGtEm9p-ZQF_XqfqyQGzZK7BS2SNp2z680QBsJiFDraEA@mail.gmail.com)を参照。64 バイトのトランザクションを無効化することでこのリスクを回避できる可能性はあるが、この問題は本提案とはおおむね独立している。これは根本的には、可鍛性(malleability)のあるブロックに対する検証状態のキャッシュに関する問題である。 ↩ -
著者らは、SPV 検証者向けに 3 つの回避策があることを把握している。1 つ目は、対象のトランザクションに加えてコインベーストランザクションについてもマークル証明を要求し、マークルツリーの深さを推定する方法である。2 つ目は、いずれかの内部ノードがビットコイントランザクションの有効なシリアライズでもあるようなマークル証明を拒否する方法である。これらの詳細についてはこちら (
https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design)を参照。3 つ目の回避策は、内部ノードをその原像の二重 SHA256 の代わりに単一 SHA256 として提供することを要求することで、マークル証明の構造を変更する方法である。完全な説明についてはこちら (https://bitslog.com/2018/08/21/simple-change-to-the-bitcoin-merkleblock-command-to-protect-from-leaf-node-weakness-in-transaction-merkle-tree/)を参照。 ↩ ↩2 -
ブロック 1,983,702 は、BIP34 (
https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki)を引き続き尊重しながら重複コインベーストランザクションを含みうる最も早い将来のブロックである。そのようなすべての将来ブロックの一覧についてはこの投稿 (https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/4)を参照。 ↩ -
技術的には、コインベーストランザクションの唯一のインプットの scriptSig のサイズは制限されているため、この上限をコインベーストランザクションに適用することはできない。 ↩
-
コインベーストランザクションに対しても実行されるロックタイム検証は、nLockTime の値がそのトランザクションが無効となる最後のブロックであり、有効となる最初のブロックではないことを強制する。 ↩
-
タイムワープ攻撃はこちら (
https://bitcoin.stackexchange.com/questions/75831/what-is-time-warp-attack-and-how-does-it-work-in-general/75834#75834)で、マーチ=ザウィ攻撃はこちら (https://delvingbitcoin.org/t/zawy-s-alternating-timestamp-attack/1062#variant-on-zawys-attack-2)で説明されている。 ↩ -
testnet4 の難易度例外は、悪用された際にブロックのタイムスタンプを未来方向へ押し進めた。これにより、一部の壊れたプールソフトウェアが 10分の猶予期間を尊重しないブロックを生成しうることが明らかになった。同様に壊れたソフトウェアがメインネットで使われる可能性について懸念を示す (
https://delvingbitcoin.org/t/timewarp-attack-600-second-grace-period/1326)者もいた。10分ではなく 2時間の猶予期間を用いても、攻撃下での期待ブロック間隔時間の短縮幅は約 2.2秒にしかならない。詳細はこの投稿 (https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/66)を参照。 ↩ -
この論点は、それらの機能のいずれかをアウトプットスクリプトで用いる、タイムロック付きの事前署名済みトランザクションを誰かが持っている場合についてのものである。そのトランザクションは有効化前にはマイニングされ得ない。そうしたアウトプットは、旧 UTXO に対する恩赦の対象にはならない。この論点に関する議論については、たとえばこちら (
https://gnusha.org/pi/bitcoindev/CAMZUoKneArC+YZ36YFwxNTKsDtJhEz5P2cosXKxJS8Rf_3Nyuw@mail.gmail.com)およびこちら (https://gnusha.org/pi/bitcoindev/CAMZUoK=1kgZLR1YZ+cJgzwmEOwrABYFs=2Ri=xGX=BCr+w=VQw@mail.gmail.com)を参照。 ↩ -
最悪ケースのブロック検証時間だけでなく、準備コストに対して課される検証時間の比率を削減することも重要である。前者は、外部の動機を持つ攻撃者が引き起こしうる被害を制限するためである。後者は、マイナーが高コストなブロックをマイニングすることで競合を妨害するインセンティブを削ぐためである。詳細はこのスレッド (
https://gnusha.org/pi/bitcoindev/VsltJ2PHqWfzG4BU9YETTXjL7fYBbJhjVXKZQyItemySIA1okvNee9kf0zAOyLMeJ4Nqv1VOrYbWns5nP4TANCWvPJYu1ew_yxQSaudizzk=@protonmail.com)を参照。 ↩ -
病的でないトランザクションは、署名操作ごとに 1 つの公開鍵を持ち、各インプットに少なくとも 1 つの署名を持つ。標準性の規定により、単一の P2SH インプットは 15 を超える署名操作を持てない。1-of-15 の
CHECKMULTISIGを用いたとしても、トランザクションは新たに導入される上限に達する前に、標準トランザクションの最大サイズに突き当たる。サイズの上限ではなく新たに導入される上限に抵触させるには、CHECKSIG DROP CHECKSIG DROP ...のような redeemScript を持つ P2SH インプットを使う必要がある。この種の redeemScript は、検証コストを増加させる以外の目的を持たず、それはまさに本提案が緩和しようとしているものである。 ↩ -
セルジオ・デミアン・ラーナーによるブログ記事 (
https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design)にて。 ↩ -
ジェレミー・ルービン「最小 64 バイトトランザクションをエンコードするマークル内部ノード原像の禁止」(メーリングリスト) (
https://gnusha.org/pi/bitcoindev/f97afcc5-54ba-4284-8e9b-e8c35c7101f6n@googlegroups.com/)。 ↩ -
技術的には、
nLockTimeの強制が本来ソフトフォークで導入された (https://bitcoin.stackexchange.com/questions/90229/nlocktime-in-bitcoin-core)ブロック 31,001 以前は、原理的には重複が常に可能だったと主張することもできる。しかし、ジェネシスブロックからnLockTimeを強制するあらゆる実装(これは特に Bitcoin Core の、また著者らが把握する他のすべての実装の振る舞いである)にとって、Consensus Cleanup 有効化後のコインベーストランザクションを重複を持たないものとして扱うことは一貫している。 ↩ -
たとえば Bitcoin Core は、BIP34 (
https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki)違反が手動で検査された特定のチェーンについてのみ、BIP30 (https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki)検証を無効化している(こちら (https://github.com/bitcoin/bitcoin/blob/390e7d61bd531505bb3d13f38316c282b85ed1dd/src/validation.cpp#L2401-L2459)を参照)。コインベーストランザクションにタイムロックを強制することで得られる保証がなければ、この扱いは Consensus Cleanup についても継続する必要があっただろう。 ↩
