sigp/discv5のテストコードを読んでノードの動作を理解する

sigp/discv5のとあるテストを読み解きながら、各ノードがどんな通信をしているのか、各ノードのk-bucketの中身はどうなっているのかを確認していくことで理解を深める。

なお、sigp/discv5のソースコードは執筆時点で最新の 02d2c896c6discv5の仕様 は v5.1 を参照する。

対象のテストコード

今回読むテストコードは こちら で、Discv5::find_node() の結果が期待通りのノード数を得られるかを確認するテスト。

ノードの起動

https://github.com/sigp/discv5/blob/f47dac2e1f59735bb0affe3502372c21d758cc4e/src/discv5/test.rs#L169

  • bootstrap node
  • 通常のnodeを3つ (node1, node2, node3)
  • target node (FINDNODEリクエストのターゲットとして指定するノード)

の合計5つのノードを起動する。

ここでのポイントは、ノードを起動する際に予め、bootstrap nodeと、その他のノード(node1, node2, node3, target node)の距離が “256” になるようにseed値を固定している。これによって、FINDNODEリクエストの結果にバラつきが出ないようにしている。

discv5における ノード間の距離 とは、ノードID(32byte)のXORの結果を対数で表したもので、sigp/discv5の実装では leading zeroの数を利用している

各ノードのノードID(途中省略)は下記。

  • bootstrap node: 0x2390..81d9
  • node1: 0xb862..63b1
  • node2: 0xbd03..5d70
  • node3: 0xe030..dcbe
  • target node: 0xf47b..3704

node1〜3にbootstrapノードを登録する

https://github.com/sigp/discv5/blob/f47dac2e1f59735bb0affe3502372c21d758cc4e/src/discv5/test.rs#L186-L199

  • bootstrap nodeに、node1, 2, 3のENRを登録する
  • node1, 2, 3に、bootstrap nodeのENRを登録する

前述の通り、bootstrapノードと、その他のノード(node1〜3、target node)の距離が “256” になるように調整されているので、各ノードのk-bucketの 256 番目のbucketに登録される。

この時点での、起動しているノードとそれらの繋がり(add_enrによって認識しているノード)は下記のようになっている

initial_kbuckets

node1 から find_node() を実行する

引数は target_node のノードID。
https://github.com/sigp/discv5/blob/f47dac2e1f59735bb0affe3502372c21d758cc4e/src/discv5/test.rs#L204-L209

メッセージの仕様

シーケンス図

sequence