Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoinネットワークのトポロジーを推定するTxProbe

Scaling Bitcoin 2019復習シリーズ第三弾は、「TxProbe: Discovering Bitcoin's Network Topology Using Orphan Transactions」

TxProbeは、Bitcoinネットワークのネットワークトポロジーを推定するための方法。ここで推定するBitcoinネットワークは基本的にパブリックに到達可能なノードで構成されるネットワークで、NATやファイアウォールの背後にあり到達不可能のノードや、インバウンド接続を受け入れないノード(軽量ノードなど)は対象外となる。

Bitcoin Coreはデフォルトで8つのアウトバウンド接続を作成する。この時選択される接続先のピアはランダムに選択されるが、/16 (ipv4)ネットワークセグメントが重複しない形で選ばれる。またこの他にインバウンド接続を受け入れる。

到達可能なノードについては、Bitnodesなどのサイトで確認できる。Bitnodesでは、getaddr/addrメッセージを利用して入手したノードに実際にアクセスするクローラーを利用して到達可能なノードを検出している。ただし、こうやって得られるのは到達可能なノードの情報のみと、それらのノードがどのようなネットワークトポロジーを形成しているかは分からない。

このノード間のエッジを推定しネットワークトポロジーを推定するための手法がTxProbeだ。

オーファントランザクションと二重使用トランザクションの扱い

TxProbeの調査方法は、Bitcoin Coreのオーファントランザクションと二重使用トランザクションのハンドリング方法に依存している。

トランザクションのハンドリング

ノードがトランザクションを受信し、検証するとそのトランザクションはメモリプールに格納され、接続中のピアに伝播される。ノードは直ぐに接続中のピアにトランザクションを送るのではなく、まずinvメッセージを使ってトランザクションの存在を通知する。そして、送信先のピアが該当トランザクションを持っていない場合getdataメッセージでトランザクションデータ自体を要求する。既に該当トランザクションを持っている場合はgetdataメッセージは送られない。

オーファントランザクションのハンドリング

オーファントランザクションのハンドリングは通常のトランザクションのハンドリングとは異なる。オーファントランザクションはそのインプットが参照するUTXOのトランザクションがまだそのノードに届いていないので、オーファントランザクションを受信してもそのトランザクションが有効なトランザクションかどうか検証することができない。そのためノードはMapOrphanTransactionsとして知られるメモリプールとは別のオーファンプールに格納される。またトランザクションの検証が出来ていないためこのオーファントランザクションが接続中のピアにリレーされることもない。

二重使用トランザクションのハンドリング

二重使用トランザクションは単純に同じコイン(UTXO)を使用する2つめのトランザクションで、このトランザクションを受信したノードは、最初のトランザクションのみを受け入れ、2つめの二重使用トランザクションは受け入れない。

基本的なネットワーク・トポロジーの推定手法

上記のトランザクションのハンドリング方法を利用すると、次のようにしてネットワーク・トポロジーの推定ができる。

まず以下の3つのトランザクションを作成する。

BitcoinBitcoinベースのアルトコインのネットワークのテストや監視、測定を行えるツールであるCoinscope*1を使用し、アリスとボブ2つのノードと接続するネットワークを仮定する。

f:id:techmedia-think:20191115134054p:plain
アリスとボブのノード間のエッジが存在する場合

Coinscopeで、

  • アリスのノードには {tx_P}を送信する。
  • ボブのノードには {tx_F}を送信する。

これが同時に到着すると仮定した場合、アリスはボブに {tx_P}をボブはアリスに {tx_F}をリレーしようとするが、お互いにとって通知されたトランザクションは二重使用トランザクションであるため、両者とも受けとったトランザクションを拒否する。

その後アリスに {tx_M}を送信する。 {tx_M}を受け取ったアリスは、それをボブにリレーする。この時点でアリスとボブのメモリプールとオーファンプールの状態は以下のようになる。

アリス ボブ
メモリプール  {tx_P},  {tx_M}  {tx_F}
オーファンプール  {tx_M}

アリスとボブのノード間にエッジが存在する場合、上記のようにボブのノードのオーファンプールには {tx_M}が存在している状態になる。このエッジが存在するかどうかの確認はCoinscopeが、ボブのノードに対して {tx_M}を通知するinvメッセージを送信した際のボブのノードの反応で判断できる。ボブとアリスの間にエッジが存在すれば、ボブは {tx_M}をオーファンプールに持っているので、invに対してgetdataを要求することはない。逆にアリスとボブのノード間にエッジが無ければ、ボブは {tx_M}について知らないので、Coinscopeのinvに対してgetdataを要求する。

以下はアリスとボブの間にエッジが存在しないパターンの構成:

f:id:techmedia-think:20191115135805p:plain
アリスとボブのノード間のエッジが存在しない場合

で、アリスとボブのメモリプールとオーファンプールの状態は↓

アリス ボブ
メモリプール  {tx_P},  {tx_M}  {tx_F}
オーファンプール

と簡単にエッジ検出できそうに思えるが、これはあくまでノード数が2つの場合に機能するが、ノード数が増えると破綻する。例えばアリスとボブの間にキャロルのノードが加わった場合に、Coinscopeがアリスに {tx_P}を送った際、 {tx_P}をアリスがキャロルにリレーするのを止められないので、ノードが増えると上記の手法はワークしない。

TxProveのトポロジー推定手法

上記の基本的な推定手法を、多くのノードが存在する状況で行えるようにするためには、TxProveでは、invBlockと呼ばれる手法を利用する。invBlockというのは、トランザクションを通知する際にinvで通知し、その要求がgetdataで来た際にトランザクションの送信を2分間ほど保留することでトランザクションの伝播を防ぐ手法(2分以上経過すると別のノードに問い合わせる)。

例えば、アリス、キャロル、ボブのネットワークを考える。

f:id:techmedia-think:20191115185556p:plain
invBlockの動作

まず、Coinscopeが全ノードに対して、 {tx_P}invを送信する。すると3ノードともそのトランザクションを要求するgetdataで返信するが、このうちアリスの要求に対してのみtxメッセージで {tx_P}を送る。すると {tx_P}を受信したアリスがキャロルに対して {tx_P}invを送信してもキャロルはすでにCoinscopeから最初に {tx_P}invを受け取っているので、アリスのinvには応答せず2分間待機している。続いて {tx_F}をボブに送信すると、ボブはそれをキャロルにリレーする。また {tx_M}をアリスに送信すると、それはキャロルにリレーされるが、キャロルは {tx_P}を持っていないので {tx_M}をオーファンとして扱い、各ノードの状態は以下のようになる。

アリス キャロル ボブ
メモリプール  {tx_P},  {tx_M}  {tx_F}  {tx_F}
オーファンプール  {tx_M}

上記のようにinvBlockの仕組みを利用することで、対象トランザクションを特定のノードに固定することができるので、この仕組みを利用して以下の手順でトポロジーを計測する。

  1. ターゲットノードを選択
  2. ターゲットノード用に親、マーカー、フラッドトランザクションを作成する。
  3. invBLockを実行する。
  4. ターゲットノード以外の全ての接続ノードにフラッドを送信し、フラッドを伝播させる。
  5. 親をターゲットに送信する。
  6. マーカーをターゲットに送信する。
  7. マーカーが伝播する。
  8. ターゲットを除くすべてのノードにマーカーを要求する。

ネットワーク内の全てのノードに対して↑を実行する。

TxProbeのコスト

mainnet(約1万のノード)でTxProbeを実行するコスト見積もりは以下のようになっている。

  • 時間: 8.25時間
  • 手数料 = (5 sat/byteとした場合) 573210〜764280 satoshi($20〜$30)

実際にmainnetでは検証されておらず、testnetで40回ほど検証が施行され、グラフ分析した結果が↓のような結果だったみたい。観測されたネットワークにはノードが733個で、6090個のエッジがあり、平均して16.6の接続数となっている。

f:id:techmedia-think:20191115191811p:plain
testnetのノードの接続数の分布

f:id:techmedia-think:20191115191849p:plain
testnetのノードグラフ

サークルの大きさは接続数の多さを表現しており、色がコミュニティを表している。ランダムグラフよりも高いコミュニティ構造を持ったグラフになっている。testnetとmainnetではインセンティブも違うのでこの傾向がmainnetにもそのまま当てはまるということはないだろうが、実際にmainnetでどのようなネットワークトポロジーが形成されているかは観測してみないと分からない。この辺、誰かmainnetで計測したりしないかなー。

なお、TxProbeは↑のようなBitcoin Coreのトランザクションのハンドリング方法に依存した仕組みなので、トランザクションの伝播方法が変わるといずれそのままでは使えなくなってしまうだろう。

*1:他のノードに接続し、接続を維持するBitcoinのネットワークプロトコルをしゃべるConnectorと、Connectorに対して要求を送る(あるノードに接続したり、メッセージを送信したりなど)Clientで構成される。