以下の内容はhttps://techmedia-think.hatenablog.com/entry/2026/02/01/162014より取得しました。


P2Pプロトコルの新機能をネゴシエートするためのfeatureメッセージを提案するBIP-434

先日BIPリポジトリにマージされたBIP-434↓

https://github.com/bitcoin/bips/blob/master/bip-0434.md

Bitcoinのような分散環境のノード実装は、他のノードと接続しメッセージを交換することでブロックやトランザクションを伝播しチェーンの同期を行う。これを行うためには、互いが送受信するメッセージを解釈し適切に処理できる必要がある。Bitcoinの実装ではこれまで、初期に実装されていたメッセージ以外にも多数の新たなメッセージを導入してきた。当然すべてのノードが一斉にバージョンアップするということはないので、接続相手がどのメッセージをサポートしているのか確認した上で適切な振る舞いをする必要がある。

P2Pプロトコルバージョン

そのためP2Pプロトコルのバージョンを定義し、ノードに接続した後に最初に送信するversionメッセージ内に自身がサポートするP2Pプロトコルのバージョンを指定することで、相手ノードにバージョンを通知している。Bitcoin Coreではこれまで以下のようにこのバージョンをアップグレードすることで新しいP2P機能を導入してきた。

バージョン 時期 Bitcoin Core 導入機能
106 2009/10 0.1.6 versionメッセージにaddress-fromnonceuser-agentcurrent block heightフィールドを追加
209 2010/5 0.2.9 addrメッセージが複数のネットワークアドレスのリストを受け入れ可能に。メッセージヘッダーにチェックサムフィールドを追加
311 2010/8 0.3.11 alertメッセージを追加
31402 2010/10 0.3.15 addrメッセージにタイムスタンプフィールドを追加
31800 2010/12 0.3.18 getheadersメッセージとheadersメッセージを追加
60000 2012/3 0.6.0 ネットワークプロトコルバージョンをBitcoin Coreのソフトウェアバージョンと分離
60001 2012/5 0.6.1 pongメッセージを追加し、pingメッセージにnonceフィールドを追加
60002 2012/9 0.7.0 mempoolメッセージを追加し、getdataメッセージを拡張しmempool内のトランザクションをダウンロード可能に
70001 2013/2 0.8.0 versionメッセージにfRelayフラグを追加。Bloom Filter用のfilterloadfilteraddfilterclearmerkleblockメッセージを追加。notfoundメッセージを追加。getdataメッセージにMSG_FILTERED_BLOCKインベントリタイプを追加
70002 2014/3 0.9.0 rejectメッセージを追加。mempoolメッセージへの応答で必要に応じて複数のinvメッセージを送信
70011 2016/2 0.12.0 NODE_BLOOMサービスビットを導入し、このサービスビットの指定がない状態でのfilter*メッセージを無効化
70012 2016/2 0.12.0 sendheadersメッセージを追加。ノードが新しいブロックのアナウンスをinvではなくheadersメッセージで受信することを優先できるように
70013 2016/8 0.13.0 feefilterメッセージを追加し、alertメッセージシステムを廃止
70014 2016/8 0.13.0 コンパクトブロックリレーのメッセージsendcmpctcmpctblockgetblocktxnblocktxnを追加。
70015 2017/1 0.13.2 0.14.2 コンパクトブロックの不正ブロックに対するBAN動作の更新
70016 2021/1 0.21.0 wtxidrelaysendaddrv2メッセージを追加

ハンドシェイク中のメッセージ送信

versionメッセージのプロトコルバージョンを使わずに導入されたP2Pメッセージもある。BIP-155BIP-339では、ハンドシェイクにおいて、versionメッセージに対してverackを送信する前に、それぞれsendaddrv2メッセージとwtxidrelayメッセージを送信するというアプローチを採っている。またBIP-330sendtxrcnclメッセージも同様。

BIP-434が提案された背景

versionメッセージを使ったプロトコルのアップグレードの問題点は、基本的にプロトコルバージョンがインクリメントされていくという点にある。ノードとしてはサポートする必要のない機能であっても、新しい機能をサポートする場合、それ以下のすべての機能をサポートしなくてはならなくなってしまう。こういった機能の展開については、インクリメントされる数値ではなく、LNのfeature bitのような表現方法の方が適している。

また、70001のアップグレードでversionメッセージにfRelayフラグを追加した際は、本来フィールド数が固定されているメッセージにオプショナルフィールドが加わると互換性問題が生じた。

また、ハンドシェイク中に送信されるメッセージについては、未知のメッセージを受け取ったノードがどのような振る舞いをするかに依存した実装になる。未知のメッセージを受け取ったノードはそのメッセージを無視するのであれば問題ないが、未知のメッセージに受け取って際に接続を切断する実装があった場合、将来的にネットワークが分断される可能性がある。Bitcoin Coreでも、version-verack間に未知のメッセージを送るとペナルティが課されるようにハンドシェイクを厳格化し(2017年)、その後wtxidrelayの提案によりversion-verack間の未知のメッセージは無視するよう方針転換(2020年)された経緯がある。

そこで、BIP-434では↑のBIP-339の仕組みを将来のP2Pのアップグレードのために一般化する提案をしている。個別のメッセージではなく、任意の新機能を通知するためのネゴシエーション機能としてfeatureメッセージを導入する。

BIP-434の使用

BIP-434をサポートするノードは、

  • versionメッセージのプロトコルバージョンとして>= 70017を設定する必要がある。
  • プロトコルバージョンが70017未満のピアに対しては、featureメッセージを送信してはならない
  • versionメッセージの後、verackメッセージの前に受信したfeatureメッセージを受け入れなければならない。
  • verackメッセージを送信した後で、featureメッセージを送信してはならない。
  • versionメッセージの後、verackメッセージの前に受信した未知のメッセージは無視すべき。
  • verackメッセージを送信した後で、featureメッセージを受信した場合、無視してもいい。
  • verack後にfeatureメッセージを送信するピアを切断してもいい。
  • featureメッセージにより対象の機能のサポートを示していないピアに、その対象機能が導入するメッセージのverack後の送信を禁止しなければならない。

featureメッセージ

featureメッセージは以下のペイロードを持つ:

名称 定義
featureid string 機能の一意識別子。長さを指定するCompactSizeの後にその長さのデータが続く。文字列はASCII文字。BIPが公開されている場合、BIP番号であるべき。
featuredata byte-vector 機能固有の設定データ。長さを指定するCompactSizeの後にデータが続く。これらのデータが解釈されるかはその機能仕様次第。サイズは512 byteを超えてはならない。不要な場合は空のバイト列になる。

ノードは、

  • サポートしていないfeatureidfeatureメッセージは無視する。
  • 認識していないfeatureidでもfeatureメッセージのペイロードが正しく解析できない場合、送信ピアを切断してもいい。

featureメッセージは1つの機能に対応しているので、複数の機能をサポートする場合は、その数分featureメッセージを送信することになる。feature bitみたいに機能ビットで機能セットを表現せずに個別に送信するのは、機能によっては、featuredataデータが必要になるからかな。




以上の内容はhttps://techmedia-think.hatenablog.com/entry/2026/02/01/162014より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14