Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoinの2106年のブロックタイムスタンプオーバーフローに対処するBitBlend提案

Bitcoinのブロックヘッダーのタイムスタンプフィールドは、32bitの符号なし整数となっており、その最大値が指す時刻は2106年2月7日6時28分15秒。

Bitcoinでは、新しくマイニングされたブロックのタイムスタンプには、過去11ブロックのタイムスタンプの中央値よりも大きな時刻を設定しなければならないというコンセンサスルールがある。そのため、2106年の最大値に達するとそれ以降新しいブロックがマイニングできなくなる。

そのため随分先ではあるものの、いずれはこの問題に対処する必要があり、その対処方法として提案されている手法の1つが2024年1月に提案されたBitBlend↓

BitBlend

https://bitblend2106.github.io/bitcoin/BitBlend2106.pdf

BitBlendでは32bitの時刻フィールドを再解釈することで、この問題を解決する。現状この時刻はUNIX時間なので1970年からの経過秒数になってる。これを完全なタイムスタンプの下位32bitとして解釈する。

このタイムスタンプの新しい解釈では、

  1. 32bitの値にゼロパディングをし64bit変数とし
  2. 1を直近11ブロックの中央値(MTP = Median Time Past)と比較し、
  3. 1の時刻がMTPの半分未満である場合、32bit制限によるオーバーフローが発生したと想定されるため、このオーバーフローを補正するために、
    • MTPの上位32bitと新しい時刻の下位32bitをブレンドし、
    • ブレンドした結果に {2^{32}}を加算する。

このルールを適用により、過去からの時刻の連続性を維持したまま、タイムスタップを64bit空間に拡張することができる。2106年のオーバーフローだけでなく、136年ごとに発生する将来の各32bitのオーバーフローも補正できる。

具体例で見ると、

2106年のタイムスタンプのMTPが4,294,967,000(0xfffffed8)で、その次のブロックのタイムスタンプの値が1,000(0x03e8)だった場合、タイムスタンプ値が4,294,967,000 / 2よりも小さいため、オーバーフローが発生したと判断され、64bit値のMTPの上位32bitの値を使って(この時点では0)以下のブレンドを実行し、

(0 << 32) | 1000 = 1000

 {2^{32}}を加算した値 {2^{32} + 1000 = 4,294,968,296}を64bitのタイムスタンプ値として評価する。

2242年ごろに2回めのオーバーフローが発生する際は、MTPを8,589,000,000(0x01fff1bd40)で、その次のブロックのタイムスタンプの値が2,000(0x07d0)だった場合、再度オーバーフローが発生したと判断され、64bit値のMTPの上位32bitの値を使って(この時点では1)以下のブレンドが実行される

(1 << 32) | 2,000 = 4,294,969,296

この値に {2^{32}}を加算した値 {4,294,969,296 + 2^{32} = 8,589,936,592}を64bitのタイムスタンプ値として評価する。

上記のように、ノードの内部ではブロックのタイムスタンプの処理は64bit表現で行うようにすることで、ノード間のもろもろのP2P通信は既存の32bitのまま行いながら、2106年以降もブロックのマイニングが可能になる。

タイムロックへの影響

Bitcoinには、

  • トランザクションのnLocktimeフィールドを用いる絶対時間ベースのCLTV(OP_CHECKLOCKTIMEVERIFY)と、
  • トランザクションインプットのnSequenceを用いる相対時間ベースのCSV(OP_CHECKSEQUENCEVERIFY)

の2種類のタイムロックのスキームがある。

両者ともブロック高を用いたタイムロック設定においては、32bitのタイムスタンプのオーバーフローの影響は受けない。

CLTVのタイムスタンプについては、2106年で自然に期限切れになる。トランザクションのnLocktimeには32bit値以上を指定できないので、そのまま機能停止して64bitに拡張しないことを↑のペーパーでは提案している。ブロック高で指定する代替手段があるので機能的な問題はないと思われる。

CSVのタイムスタンプについては、上記のBitBlendの仕組みにより2106年以降もこれまでと同様に動作する。CSVのチェックには2つのチェックがある、

まず、

UTXOが参照するトランザクションのブロックの時刻+相対的なオフセット≦ 現在のブロックの時刻

これはスクリプトインタプリタの外部で行われるチェック。

もう1つは、インタプリタで行われる以下のチェック

スクリプト内で指定されたCSVの値 ≦ nSequenceフィールドの値

実際の時刻のチェックは、前者で行われ、そのブロック時刻はBitBlendにより64bitで行われる。内部の時刻が64bitになるだけで現状と同じ動作になる。

というのがBitBlendの提案。既存のインタプリタやP2Pメッセージへの影響を最小限にしながら、オーバーフローに対処する提案になってる。