Satoshi Client Node Discovery

提供: tezos-wiki
移動先: 案内検索

概要[編集]

Satoshiクライアントは、いくつかの異なる方法でノードのIPアドレスとポートを検出します。

#ノードはさまざまな方法で自分の外部アドレスを発見します。 #ノードは、それらに接続するリモートノードのコールバックアドレスを受け取ります。

  1. Nodesは、IPアドレスを受け取るようにDNS要求を行います。

#ノードはソフトウェアにハードコードされたアドレスを使用できます。 #ノードは他のノードとアドレスを交換します。 #ノードはデータベースにアドレスを格納し、起動時にそのデータベースを読み込みます。 #ノードにはコマンドライン引数としてアドレスを与えることができます #ノードは、起動時にユーザが提供するテキストファイルからアドレスを読み込みます

タイムスタンプは各ノードのノード アドレスが最後に確認されました。 net.cppのAddressCurrentlyConnectedが処理します メッセージがノードから受信されるたびにタイムスタンプを更新する。 タイムスタンプはアドレス上でのみ更新され、データベースに保存されます タイムスタンプが20分以上経過したとき。

どのタイプのノード接続に関する情報については、ノード接続の記事を参照してください。 実際にノードに接続するときはアドレスが優先されます。

最初のセクションでは、ノードがどのように要求を処理するかについて説明します。 "getaddr"メッセージを介してアドレスの役割を理解することによって タイムスタンプを使用すると、タイムスタンプが保持される理由がより明確になります 彼らは住所が発見されるそれぞれの異なる方法のためです。

メッセージ "getaddr"の処理[編集]

ノードが "getaddr"リクエストを受信すると、ノードは最初に何個 過去3時間以内にタイムスタンプを持つアドレス。 その後、それらのアドレスを送信しますが、2500を超えるアドレスがある場合 過去3時間に見た場合、利用可能な広告のうち約2500個を選択します ランダムな選択を使用して最近のアドレス。


ここで、ノードがノードアドレスについて知る方法を見てみましょう。


発見方法[編集]

ローカルクライアントの外部アドレス[編集]

クライアントは、外部のルーティング可能なIPアドレスを決定するために情報を返すパブリックWebサービスを使用します。

クライアントはThreadGetMyExternalIPというスレッドを実行します(net.cpp)。 外部から見たクライアントのIPアドレスを特定しようと試みます 世界。

まず、91.198.22.70ポート80に接続しようとします。 checkip.dyndns.orgサーバー。接続に失敗すると、DNS要求が行われます checkip.dyndns.orgのために接続が試行されます。 次に、74.208.43.192ポート80に接続しようとします。 www.showmyip.comサーバー。接続に失敗すると、DNS要求が行われます www.showmyip.comのために、そのアドレスに接続が試みられます。

上記で試行したアドレスごとに、クライアントは接続を試みますが、 HTTPリクエストを送信し、適切な応答ラインを読み込み、 それからのIPアドレス。 これが成功すると、IPアドレスが返され、接続されている任意の ノードが終了し、スレッドは終了します(次の 住所)。

コールバックアドレスを接続[編集]

ノードが最初の「バージョン」メッセージを受信し、そのノードが接続を開始すると、ノードはそのアドレスをリモートにアドバタイズし、必要に応じてローカルノードに接続できるようにします。

自身のアドレスを送信した後、遠隔ノードのバージョンが最近のものか、ローカルノードがまだ1000のアドレスを持っていない場合に、より多くのアドレスについて知るために、 "getaddr"要求メッセージを遠隔ノードに送る。


IRCアドレス[編集]

バージョン0.6.x以降、BitcoinクライアントはデフォルトでIRCブートストラップを使用しなくなり、バージョン0.8.2ではIRCブートストラップのサポートが完全に削除されました。このドキュメントは、ほとんどの旧バージョンでは正確です。

ノードは、自身のアドレスを学習し共有することに加えて、IRCチャネルを介して他のノードアドレスについて学習しました。 irc.cppを参照してください。

独自のアドレスを学習した後、ノードは独自のアドレスを文字列にコード化してニックネームとして使用します。次に、#bitcoin00と#bitcoin99の間で指定されたIRCチャネルにランダムに参加しました。その後、WHOコマンドを発した。スレッドは、チャネルに現れたときに行を読み取り、チャネル内の他のノードのIPアドレスをデコードします。これはノードがシャットダウンされるまで永遠にループで実行されました。

クライアントがIRCからアドレスを発見すると、アドレスのタイムスタンプを現在の時刻に設定しましたが、51分の "ペナルティ"を使用していました。

DNSアドレス[編集]

起動時に、ピアノードの探索が必要な場合、クライアントはDNS要求を発行して、他のピアノードのアドレスについて学習します。クライアントには、シードされるDNSサービスのホスト名のリストが含まれています。 2017年12月現在、リスト(chainparams.cpp <ref> bitcoin / src / chainparams.cpp at masterのリスト< / ref>)には以下が含まれます:

  • seed.bitcoin.sipa.be
  • dnsseed.bluematt.me
  • dnsseed.bitcoin.dashjr.org
  • seed.bitcoinstats.com
  • seed.bitcoin.jonasschnelli.ch
  • seed.btc.petertodd.org

DNS応答には、要求された名前の複数のIPアドレスを含めることができます。

DNSによって発見されたアドレスは、最初はタイムスタンプがゼロであるため、「getaddr」要求に応じてアドバタイズされません。

ハードコーディングされた "シード"アドレス[編集]

クライアントには、ビットコインノードを表すハードコードされたIPアドレスが含まれています。

これらのアドレスは、アドレスを全く生成していない他の方法がない場合、最後の手段としてのみ使用されます。接続処理スレッドThreadOpenConnections2()のループが空のアドレスマップを参照すると、バックアップとして「シード」IPアドレスが使用されます。

可能であればシードノードから離れていくというコードがあります。これらのノードが過負荷にならないようにすることが前提です。ローカルノードに(おそらくシードノードから学んだ)十分なアドレスがあれば、接続スレッドはシードノード接続を閉じます。

シードアドレスには最初にゼロタイムスタンプが与えられ、 したがって、 "getaddr"要求に応答してアドバタイズされません。

進行中の "addr"広告[編集]

ノードは、アドレスを中継するとき(以下参照)にアドレスをアドバタイズするので、ノードが "getaddr"要求を送信した後に "addr"メッセージ内のアドレスを受信するか、接続が確立されたとき。

アドレスが本当に古いバージョンのものであれば無視されます。それほど古いバージョンでない場合は、すでに1000のアドレスがある場合は無視されます。

送信者が1000を超えるアドレスを送信した場合、それらはすべて無視されます。

"addr"メッセージから受信したアドレスはタイムスタンプを持っていますが、タイムスタンプは必ずしも直接受け入れられるとは限りません。


メッセージのすべてのアドレスについて: #タイムスタンプが低すぎたり高すぎたりする場合は、5日前に設定されます。 #タイムスタンプから2時間を引いてアドレスを追加します。

何らかの理由でアドレスが追加されると、AddAddress()を呼び出すコードは、それが既に存在するかどうかを確認しません。 net.cppのAddAddresss()関数がそれを行い、アドレスがすでに存在する場合は、さらに処理してアドレスレコード。アドレスの広告されたサービスが変更された場合、それは更新されて保存されます。

アドレスが過去24時間に表示され、タイムスタンプが現在60分以上経過している場合は、60分前に更新されます。

アドレスが過去24時間に表示されず、タイムスタンプが現在24時間以上経過している場合は、24時間前に更新されます。

アドレスリレー[編集]

"addr"メッセージ(上記参照)からアドレスが追加されると、それらは他のノードにリレーされます。まず、次の基準を設定する必要があります[9]。

#処理後のアドレスタイムスタンプは現在時刻の60分以内です # "addr"メッセージには10個以下のアドレスが含まれています #およびfGetAddrがノードに設定されていません。 fGetAddrはfalseを開始し、ノードからアドレスを要求するとtrueに設定され、ノードから1000未満のアドレスを受け取るとクリアされます。 #アドレスはルーティング可能でなければなりません。

上記の基準を満たすすべてのアドレスについて、ノードはアドレス、現在の日付(整数形式)、およびランダムな256ビット値(クライアントの起動時に生成される)をハッシュします。ノードは、最も低いハッシュ値を持つ2つのアドレスを取り、それらに「addr」メッセージを中継する。これにより、各ノードは、ある時点で2つの他のクライアントに「addr」メッセージを中継し、他の2つのクライアントはランダムに選択され、ランダム選択は少なくとも24時間に1回以上開始される。

自己放送[編集]

24時間ごとに、ノードは、接続されたすべてのノードに自分のアドレスをアドバタイズします。

また、リモートノードが持っていると思うアドレスのリストもクリアされ、ノードへの送信がリフレッシュされます。このコードはmain.cppのSendMessages()にあります。

古い住所のクリーンアップ[編集]

main.cppのSendMessages()には、古いアドレスを削除するコードがあります。

これは、3つのアクティブな接続がある限り、10分ごとに実行されます。

ノードは、マップに少なくとも1000のアドレスがある限り、消去プロセスが20秒を超えない限り、14日以内に使用されなかったメッセージを消去します。

データベースに格納されているアドレス[編集]

AddAddress()が呼び出されると、アドレスがデータベースに格納されます。

AppInit2()がdb.cppにあるLoadAddresses()を呼び出すと、起動時にアドレスが読み込まれます。

現在のところ、アドレスが保存または更新されるたびに、すべてのアドレスが一度にすべて格納されているように見えます。<ref> [http://bitcointalk.org/index.php?topic=26436.0 Bitcoin起動時にたくさんのディスクアクティビティ: / ref>実際、AddAddressはさまざまなテストで0.1秒以上かかると見られ、通常はクライアントを起動してから12時間後には何万回も呼び出されます。

コマンドラインで提供されるアドレス[編集]

ユーザーは、接続するノードを指定することができます。  -addnode <ip> コマンドライン引数。複数のノードを指定することができます。

コマンドラインで指定されたアドレスには、タイムスタンプがゼロに設定されているため、「getaddr」リクエストに対する応答としてアドバタイズされません。

ユーザーは、接続するアドレスを-connect <ip> コマンドライン引数。複数のノードを指定することができます。

-connect引数が-addnodeと異なる点は、-connectアドレスがアドレスデータベースに追加されず、-connectが指定されている場合は、それらのアドレスだけが使用されることです。

提供されたテキストファイル[編集]

クライアントは自動的にbitcoinデータディレクトリ内の "addr.txt"という名前のファイルを読み込み、そこに見つかったアドレスをノードアドレスとして追加します。これらのノードには、他のアドレスよりも特別な設定はありません。それらはプールに追加されたばかりです。

テキストファイルからロードされたアドレスは、最初はゼロタイムスタンプが与えられているため、「getaddr」要求に対する応答としてアドバタイズされません。


関連項目[編集]

参考文献[編集]

<リファレンス/>

Category:開発者 Category:技術