Develop with pleasure!

福岡でCloudとかBlockchainとか。

Testnet 4の仕様を定義したBIP-94

現在のTestnet 3を置き換えるTestnet 4の仕様がBIP-94としてBIPにマージされた↓

https://github.com/bitcoin/bips/blob/master/bip-0094.mediawiki

testnetのリセットは、

  • 金銭的価値のないtestnetのコインが詐欺まがいのエアドロップや売買に使用されていたり、
  • マイニング報酬が既に約0.014 BTCまで低下していて、マイニングしてもtestnetコインを配布しづらくなっている
  • (↑を助長した)ブロックストーム問題

などが理由とされている。

Testnet 4の変更点

Testnet 4では、ジェネシスブロックから現在mainnetで有効な機能はすべて有効になっている。つまり、最新のTaprootまでのアクティベート済みのソフトフォークが有効になっている。

また、Testnet 4は単にtestnetをリセットするわけではなく、リセットに伴いブロックストームやタイムワープ攻撃への対応が組み込まれている。

ブロックストーム問題

BitcoinのPoWでは、ブロックの生成間隔が平均10分になるように、2016ブロック毎にPoWの難易度の調整が行われる。ただ、ブロック報酬のため常にハッシュパワーが投入され続けるmainnetとは違い、testnetのコインには金銭的な価値がないため、投入されるハッシュパワーが一定ではなくブロック生成間隔が予測しづらい。そのため、前のブロックから20分間ブロックが作られなかったら、難易度を最小難易度=1にしてブロックをマイニングすることができる機能がTestnet 3から導入されている。

20分ほどタイムスタンプがずれたブロックを作成すれば最小難易度でブロックが作成できるものの、一方でノードの時計と比較して2時間以上先のタイムスタンプを持つブロックは拒否される。そのため、20分ルールで一度に作成できるブロックは最大6個まで。

このtestnet特有の20分ルールと難易度調整のロジックの組み合わせには実は問題があった。難易度調整の仕組みは基本的に2016ブロックの期間すべて同じ難易度でブロックが作成されていることを前提としており、2016ブロックの最後のブロックの難易度の値をもとに次の期間の難易度を計算する。mainnetであればこれは問題なく動作する。ただtestnetで、2016ブロックの期間の最後のブロックが上記の20分ルールで作られた場合、その期間の難易度は最小難易度=1で、それを元に次の期間の難易度が計算されてしまう。

この結果、testnetの難易度の極端な変動が発生し、直後の期間では急スピードでブロックが生成されるようになる。数週間で3年分のブロックがマイニングされるなど、ネットワークが実質使用不能な状態になったみたい。

対策

このブロックストーム問題への対応として、Testnet 4では難易度調整を行う際に、

  • 前のブロックの難易度を2016ブロックの最後のブロックではなく最初のブロックから取得する

という変更を加えている。もともと期間の先頭のブロックには20分ルールを適用できないので、これにより20分ルールを利用した難易度調整の細工はできなくなるというもの。

タイムワープ攻撃

各ブロックのタイムスタンプは、そのブロックの前11ブロックのタイムスタンプの中央値*1より高い値を設定しなければならないMTP(Median-Time-Past)というルールがある。しかし、中央値よりも1秒でも大きければいいので、マイナーは過去11ブロックの中央値 + 1秒を設定することで、チェーン上のタイムスタンプの進行を遅らせることができる。

そして難易度調整では、2016ブロックを生成するのにかかった時間が目標時間(2016ブロック×10分)より

  • 長かった場合は、難易度を下げ
  • 短かった場合は、難易度を上げる

という調整が行われる。ここ時、実際に生成するのにかかった時間は、2016ブロックの期間の最後のブロックのタイムスタンプから最初のブロックのタイムスタンプを差し引いた値で計算される。これを悪用し、

  1. 2016ブロックの内、最初の2015ブロックについて、MTPのルールを満たす最小限のタイムスタンプとなるよう調整し、最後のブロックについては2時間後のタイムスタンプを設定する。
  2. そして、その次の2016ブロック期間の最初のブロックについては、MTPに基づき直近11ブロックの中央値のタイムスタンプをベースにできる。つまり約2週間のタイムスタンプを設定する。
  3. 1と同様の方法で期間の最終ブロックまでのタイムスタンプを設定し、最後のブロックを2時間後に設定する。
  4. 3の結果、2016ブロックの生成に2週間ではなく4週間かかったと認識させることができ、難易度を下げることができる。これを繰り返す。

これがタイムワープ攻撃の手法。タイムスタンプの設定を細工することで、マイニングの難易度を下げることが可能になるが、この攻撃を成功させるためには

  • 51%以上のハッシュパワーが必要になり、
  • その他のマイナーが妨害しやすく
  • 攻撃が行われていることがすぐに分かる

ことから、すべてのマイナーが結託してやらないと現状のBitcoinのマイニング状況では攻撃を成功させるのが難しい。

対策

タイムワープ攻撃への対策として、元々mainnetへのソフトフォークとして提案されているコンセンサスクリーンアップの内容の一部でもある以下のルールがTestnet 4には追加されている。

  • 2016ブロック毎の難易度調整期間の最初のブロックのタイムスタンプは、直前のブロックのタイムスタンプの2時間(7200秒)600秒前より前の時刻であってはならない。

元々の提案では600秒だったのが7200秒になっているが、最近のPRのコメントを見るに600秒に戻るかも?

以下のPRにより、600秒に戻った模様。

Revert "Change BIP 94 timewarp delta to 7200 seconds" by fjahr · Pull Request #1660 · bitcoin/bips · GitHub

ネットワークパラメーター

ジェネシスブロックのデータは↓

  • タイムスタンプ:1714777860(2024-05-04 08:11:00 +0900)
  • nonce:393743547
  • nBits:0x1d00ffff
  • バージョン:1

でコインベーストランザクションには、以下のメッセージが埋め込まれる。

03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e

既存のtestnetのジェネシスブロックに埋め込まれているメッセージはmainnetのジェネシスブロックと同じものだったけど、Testnet 4のジェネシスブロックには、現在のmainnetのブロック842,000のハッシュ値000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00eが埋め込まれている。これは、このブロックより前にTestnet 4のブロックがプレマインされていないことを示している。

結果、コインベーストランザクションのhex値は、

01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5504ffff001d01044c4c30332f4d61792f323032342030303030303030303030303030303030303030303165626435386332343439373062336161396437383362623030313031316662653865613865393865303065ffffffff0100f2052a010000002321000000000000000000000000000000000000000000000000000000000000000000ac00000000

ブロックヘッダーは、

0100000000000000000000000000000000000000000000000000000000000000000000004e7b2b9128fe0291db0693af2ae418b767e657cd407e80cb1434221eaea7a07a046f3566ffff001dbb0c7817

結果、ジェネシスブロックのハッシュ値は、

00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043

また、P2Pメッセージの先頭に付与されるマジックバイトが、0x1c163f28になる。この値自体は特に意味のあるものではなくランダム値とのこと。

後方互換

Testnet 4はTestnet 3と後方互換性があるため、Testnet 3をサポートしているソフトウェアは、ネットワークパラメーターを追加するだけで、最低限動作するようになる。

ただ、上記の変更に伴い追加されているルールに違反するブロックを受け入れる可能性があるため、追加ルールも実装することが推奨されている。

実装

Testnet 4に対応するBitcoin CoreのPRもマージされた↓

github.com

*1:平均値だと悪意ある操作がしやすいため