Develop with pleasure!

福岡でCloudとかBlockchainとか。

WTXIDを使ったP2Pリレーの仕様を定義したBIP-339

Bitcoinトランザクションをリレーする際は、接続中のピアに対してinvメッセージでトランザクションを通知し、相手のピアがそのトランザクションを持っていない場合、getdataメッセージでそのトランザクションデータを要求する。この際のトランザクションの識別子にはtxidが使われている。この振る舞いはSegwit導入後も同じまま。

Segwitトランザクションでは、インプットの署名データはwitnessと呼ばれる領域に移され、txidを計算する際にこのwitnessのデータは含まれない。つまりtxidはwitnessのデータにコミットしていない。このtxidとは別にwitnessのデータも含めて計算しているのがwtxidトランザクションデータの内、唯一改変が可能なデータがインプットのscriptSigのデータだったのが、SegwitによりscriptSigは空になったので、txidのmalleabilityは排除されたが、wtxidにはmalleabilityは存在する。

この状況では、Segwitトランザクションをリレーする際、受信したトランザクションがポリシー違反であったり無効な場合でも、そのトランザクションをダウンロードする必要がある。この時、同じtxidトランザクションが再度通知されても、実はwitnessのデータが変わっていて、その場合正しいトランザクションかもしれないので、再度ダウンロードしてチェックする必要がある。txidだけではwitnessに変更があるのかどうか判断できないためだ。こういった妨害の懸念を解消するために、トランザクションリレーにwtxidを使おうという提案が、BIP-339の内容↓

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

新しくwtxidrelayというペイロードが空のメッセージを追加し、ハンドシェイク時に送信することでinvgetdataで使う識別子をwtxidにする模様。以下、BIPの意訳。

概要

このBIPは、トランザクションのtxidではなく、BIP-141のwtxidをベースにしたトランザクションリレーをサポートするためのP2Pプロトコルの2つの変更を記述する。

動機

歴史的に、BitcoinP2Pネットワーク上でトランザクションを通知するために送信されるINVメッセージは、そのトランザクションのハッシュであるtxidによってトランザクションを参照していたが、これはwitnessを含まないトランザクションのハッシュである(BIP-141参照)。これはSegregated Witness(BIP 141/143/144)がネットワークで採用されてからも同様だ。

witnessにコミットしないトランザクションの通知は、非効率性を生む。トランザクションのwitnessはtxidを変更することなく変更できるため、ノードが受け入れないwitnessトランザクションを受信したノードは、他のピアによって通知された場合、通常は同じトランザクションをダウンロードする。これは、そのtxidでトランザクションを拒否した後で、特定のtxidをダウンロードしないという代替手段は、第三者トランザクションwitnessを悪用し、結果無効なトランザクションをノードに通知することで、トランザクションリレーを妨害し、有効なトランザクションのリレーも同様に妨害するからである。

トランザクションの通知や取得時にwtxidを使用することでこの懸念を解消することができる。

仕様

  1. 新しくwtxidrelayメッセージを追加する。これはpchCommand == "wtxidrelay"の空のメッセージとして定義される。
  2. このBIPを実装するノードのプロトコルバージョンは70016以上に設定する必要がある。
  3. wtxidrelayメッセージは、プロトコルバージョンが70016以上のピアからのVERSIONメッセージへの応答でVERACKメッセージを送信する前に送信する必要がある。
  4. INVメッセージおよびGETDATA要求の両方で使用するため、参照されるハッシュがトランザクションのwtxidであることを示すため、新しいinvタイプMSG_WTX (0x00000005)が追加された。GETDATA要求の場合、MSG_WTXは要求されているトランザクションが同様にBIP-144で定義されるwitnessでシリアライズされるべきであることを意味する。
  5. ノードがピアとの間でwtxidrelayメッセージを送受信した後は、ノードはそのピアに対するトランザクションの通知や、そのピアから通知されたトランザクションを要求する際、MSG_WTXinvタイプを使用することが求められる。

後方互換

wtxidベースのトランザクションリレーは、両方がサポートするピア間でのみ有効になるため、この変更後も古いクライアントは完全に互換があり、相互運用可能だ。

実装

https://github.com/bitcoin/bitcoin/pull/18044