IRCブートストラッピングについて
1週間ほど前、#bitcoinと#bitcoin-devチャンネルでとても親切なFreenodeのスタッフに出会った。彼は#bitcoinチャンネルがボットネットのコマンド・アンド・コントロールチャンネルのように見えるとしてFreenodeのレーダーに引っかかったと教えてくれた。しかし、ビットコインの仕組みとIRCが必要な理由を説明したところ、現在の規模であればチャンネルは問題ないと言ってくれた。
しかし、これがきっかけで考えるようになり、その週の後半にIRCでもこの話題を議論した。その結果、IRCはブートストラッピングには不適切な方法であるという結論に至った。特に現在の形式においてはなおさらだ。現在、各クライアントはIRCに接続し、接続し続ける。/whoコマンドとjoinメッセージを使い、クライアントは発見したIPにポート8333で接続するブートストラッピング方式を取っている。しかし、クライアント同士はビットコインプロトコルを通じて内部的にも通信し、新しいノードをブロードキャストしている。それでもなお、常にIRCに接続し続けている。これにはいくつかの欠点がある:
ブートストラッピングにIRC接続が必要(ファイアウォールがしばしばブロックし、FreenodeはTORをブロックする)単一障害点がある(Freenode)自前のインフラを使わずFreenodeのサービスにただ乗りしている。多くのサーバーは実際にMOTDでボット接続を禁止している。些細な点:ビットコイン内の追加プロトコルが余計な複雑さをもたらしている このフォーラムには常時稼働しているビットコインIPのリストがすでに出回っており、良いアイデアではあるが、あまりスケーラブルではない。そこで以下の解決策を提案する:GnutellaとMUTEは非常に似たブートストラッピングの問題に直面している。それを解決するために、「Gnutella Webcache」のリストに依存している。これらのWebcacheはボランティアがシンプルなPHPサーバー上で運用しており、マスターリストが各Gnutella/MUTEリリースに同梱されている。クライアントがネットワークに参加したい場合、HTTPを通じてWebcacheの1つか2つに他のノードのリストを問い合わせ、自身もそのリストに追加される(通常、最後にX件確認されたクライアントのリストだ)。数時間(または数日)ごとに、実行中のクライアントはWebcacheに再接続し、まだ稼働中でリストから削除する必要がないことを通知する。ビットコインにも同じ仕組みを実装することを提案する。ボランティアが安価なPHPウェブスペースでこれらのWebcacheを運用し、SatoshiまたはSiriusにURLを伝え、各リリースにリストを追加してもらう。これにより、制限的なファイアウォールやTOR環境下のユーザーも手動でノードを探すことなくビットコインを使用でき、はるかにスケーラブルなアプローチとなる。(おまけとして、whatismyip.comなどへのHTTPコールも不要になる)
もちろん、ビットコインのブートストラッピングにはもっと良いアイデアがあるかもしれないし、ぜひ聞きたい。あるいはWebcacheのアイデアへの提案でも。ぜひここに投稿してほしい!
よろしく、 soultcer
セグメンテーションを排除するために、すべてのピアが他のすべてのピアのリストを持つべきだ。Torにも同じ要件があるので、Torを真似るべきだ:信頼できるディレクトリサーバーが定期的にすべてのピアの署名付きリストを作成し、HTTPで公開する。すべてのBitCoinクライアントがディレクトリミラーとして機能するオプションを持ち、それはdirServersのリストに示される。生成者はリストへの追加を依頼する必要がある(このリストにはそのピアが受け入れる最大接続数などの情報も含められる)が、単にトランザクションを行いたい人はdirMirrorからリストを取得して、いくつかのランダムなピアに接続すればいい。
これが中央集権的すぎるなら、I2Pがやったように、誰でもディレクトリサーバーになれるようにすることもできる。ただしその場合、dirServerが不正を働いた時に検出できる必要がある。
個人的にはI2P方式に一票だ。うまく動く。
soultcer、Freenodeのスタッフと話してくれてありがとう。現在の規模では問題ないとわかって良かったし、彼らに私たちの存在を知ってもらえた。TORのようなプロジェクトを支援しているので、おそらく私たちにも好意的だろう。歓迎されすぎないようにしたいものだ。もし大きくなりすぎたら、同じ理論で、もうIRCは必要ないほど大きくなっているということなので、退出する。
IRCが必要だったのは、静的IPを持つ人がいなかったからだ。初期にはいくつかの安定した支持者がいたが、全員が数日ごとに変わるプール割り当てのIPを持っていた。IRCは一時的な解決策にすぎない。Bitcoinに組み込まれたaddrシステムが主な解決策だ。
Bitcoinは任意のBitcoinノードからIPリストを取得できる。その意味で、すべてのノードがディレクトリサーバーとして機能している。
現在のバージョンが使われなくなるまでに少なくとも1つはまだ稼働している可能性が十分にある静的IPノードが揃えば、シードリストをプリプログラムできる。
シードリストをどのようにまとめるべきだと思うか?しばらく静的だった現在接続中のIPから作成するのは大丈夫だろうか?
ちなみに、別のディレクトリサーバーソフトウェアを展開して補完したい場合、IRCを提案してもよいだろうか?IRCは良いディレクトリサーバーだ(他の用途もあると聞いている)。誰でも実行できる成熟したIRCサーバー実装が利用可能だ。BitcoinのIRCクライアント実装は既に十分にテストされている。
ブートストラップの可用性を確保するためにFast Flux [1]ネットワークで協力する、複数のエンティティが所有するDNSサーバーのセットに興味がある人はいるか?
IRCの何が問題なんだ? ピアリストを交換するために使われるもう一つの方法にすぎない。接続を阻止して-addnode=1.2.3.4を使い、ブートストラップ用の既知のノードに接続すればいい…
ノードがリストを取得した後にIRCから切断すると、ブートストラップしようとしているノード以外は空になるので、ブートストラップには使えなくなる。
Gnutellaが使っているような分散型ホストキャッシュのアイデアは良いと思う。現時点では、大多数の人にとってIRCは単一障害点だ。何らかの理由でFreenodeのチャンネルがなくなったと仮定しよう。Freenodeが嫌気がさして閉鎖したのかもしれない。MenInBlackが俺たちのシステムを見て狂ったように笑い、Freenodeに閉鎖するよう圧力をかけたのかもしれない。
クライアントを起動しても何も起きない。コマンドラインに移って「-addnode」(あるいは-peer? まあいい)とタイプして既知のノードに接続することはできるが、その時点でノードを知っている必要がある。俺たちにとってはそれほど難しくないだろうが、新規ユーザーはどうか? ウェブサイトにピアリストを置くこともできるが、その時点で「キラキラした金貨をダブルクリックして取引開始」から「ウェブサイトで更新されたピアリストを確認し、コマンドプロンプトを開き、bitcoinディレクトリに移動し、正しいピアをタイプして…」になってしまう。もしMIBが追ってきているなら、ウェブサイトもとっくになくなっているだろう。
もちろん、addpeerをもっとユーザーフレンドリーに実装することもできる。「ネットワークに接続できません。ピアを入力してください:」というポップアップに、見つけ方の説明を添えて。しかしその時点で、技術的問題に対してソーシャルな解決策を作っていることになる。
また、大きくなればいずれにしてもIRCから移行する必要がある(OPのFreenodeスタッフとの会話が示唆するように)。Torユーザーはどうか? 匿名にするためにTorを使いたい人が、なぜ手動でピアを追加しなければならないのか?
最後に、Freenode上の誰でも、実行中のすべてのBitcoinクライアント、いつオンラインになったか、いつオフラインになったかなどのリストを簡単に取得できる。これはプロジェクトの公言する匿名性の目標に反する。もちろん、ホストキャッシュシステムでも、そのキャッシュに接続した人はサーバーオペレーターに記録されうるが、一人のオペレーターがネットワークの全体像を把握することはない。
IRCソリューションは素晴らしい出発点であり、その安定性が証明されたことを称賛する。ネットワークを簡単に立ち上げ、プログラムのより興味深く重要な検討事項に集中するという素晴らしい判断だった。ただ、Bitcoinはいつかそれを卒業すると思う。まだなら。
Bitcoinには「addr」メッセージを使った独自の分散型アドレスディレクトリがある。現在の長期稼働している静的ノードのリストをシードとしてコードに組み込む時期が来た。新しいノードがシードノードに優先的に接続し続けないようにするコードを追加できる。接続してリストを取得するだけなので、シードノードの負担にはならない。
どう思うか、シードの追加を進めるべきだろうか?
最初にIRCを試すことに変わりはない。IRCにはリスト上にいるために接続を維持する必要があるため、現在オンラインのノードをリストアップできるという利点があるが、単一障害点であるという欠点がある。「addr」システムには単一障害点がないが、最近見られたノードしか教えてくれないため、試したノードの一部がオフラインになっているので、接続に少し時間がかかる。両方の組み合わせにより、両方の長所と、より高い全体的な堅牢性が得られる。
Freenodeが我々にうんざりした場合に備えて、IRCサーバーを運用するボランティアをしてくれる方はいるか?
使えるIRCサーバーを運用している。かなり安定しているが、冗長な接続ではない。今のところ2つのサーバーだけだが、いじったりはしない。ただ動いている。
俺のマシンは専用のIRCサーバーだ。
これはP2Pにおいてよく知られた問題で、Original Introductionと呼ばれている。ブートストラッピングも良い用語だ。ブートストラッピングの問題点は、分散化できないことにある。IRCであれHTTPであれDNSであれ、クライアントにはアドレスまたはアドレスリストがハードコードされている必要があり、リストされたアドレスの少なくとも1つがまだ有効であるほど十分に新鮮でなければならない。最初のノードに到達した後は、もはやOriginal Introductionモードではなくなり、ゴシップなどの分散化のための全技術を使用できる。もちろん、ネットワークから切断され、既知のピアがすべていなくなった場合は、ブートストラッピングに戻ることになる。
ブートストラッピング方式を選ぶ際に相反する2つの特性がある:堅牢性(スケーラビリティ/信頼性)と鮮度だ。堅牢性は、HTTPピアリストで一般的に行われるように、複数のサーバーにキャッシュすることで鮮度を犠牲にして向上する。鮮度は、IRCのように全員が接続した状態にすることで堅牢性を犠牲にして最大化される(少なくともTCPタイムアウトまでは)。もちろん、ブートストラップが成功するためには両方が必要なので、堅牢性と鮮度の適切なバランスを見つけることが鍵だ。
現在気に入っているブートストラッピング方法をいくつか挙げる:
ダウンロード時に実行ファイルまたはインストーラーに最新のピアリストを動的に追加する方法。通常、ユーザーはアプリケーションを公式ウェブサイトから入手するので、ウェブサイトはすでに新規ユーザーにとっての障害点だ。アプリケーションにはすでにブートストラップに使用するアドレスがハードコードされている。だから、ダウンロード時に最新のピアを追加すればいい。実行ファイルの末尾からリストを読み取るための凝ったコードが必要だが、NSISインストーラーでこれを実装したことがあり、それほど難しくはない。ほとんどのソフトウェア開発者はこの方法に抵抗を感じるが。
XMPPを介してGoogle App Engineアプリケーションに接続する方法。これはIRCの鮮度を持ちつつ、よりスケーラブルな堅牢性がある。App Engineは主にウェブアプリ向けだが、メールとXMPPの処理も提供している。XMPPまたはHTTPのいずれかで同じハンドラーコードを使ってピアリストを扱える単一のアプリケーションを書くのは簡単だ。現在あるアプリケーションでこれを使っており、うまく動作し非常に信頼性が高い。フォールバック用に第2のApp Engineがあればいいのだが、たまにダウンタイムがあるので。
IRCやXMPPのようなプロトコルの複雑さをすべてのノードに要求する代わりに、ネットワーク上にいくつかの特別なセンチネルノードを置く方法がある。これらはアクティブなノードが利用できる通常の分散手法を使って、接続されたノードのアドレスを収集する。センチネルノードは定期的に最新のアドレスをアップロードする。たとえばHTTP POSTで複数のウェブサイトに。新しいノードは、現在機能しておりアクセス可能なウェブサイトのいずれかから最新のアドレスリストをダウンロードできる。5つのセンチネルがそれぞれ5分ごとにアップロードすれば(ずらして)、約1分ごとに更新される。これは鮮度の点でIRCと同等であり、HTTPミラーの数とセンチネルの数を変えることで必要なだけ堅牢にできる。
eMuleがKADネットワークのブートストラッピングを処理する方法は、かなり最適に近いと思う:
既知のピアのリストはファイル(nodes.dat)に保存され、各クライアントがそのファイル内の既知ノードのリストを維持する(最長稼働時間でソートされていると思う――これはKademliaの固有の特性だが、それでも良いアイデアだ)。リリースされるクライアントには、静的IPアドレス上の信頼できるピアのアドレスを含むそのようなファイルが同梱されるべきで、そこから新しいクライアントが接続先のアドレスを取得できる(そして自分のファイルに保存する)。
「シードリスト」が古くなったり、サーバーがシャットダウンしたりした場合は、ネットワーク上の誰にでも自分のnodesファイルを公開してもらえばいい(たとえばrapidshareで)。すると、接続できるIPアドレスの最新リストが手に入る。
SVNバージョンでは、まずIRCを試し、それが失敗した場合はハードコードされたシードノードのリストにフォールバックするようになった。次のリリースまでにシードノードの多くがまだ稼働しているはずだ。シードノードにはアドレスリストを取得するために一時的に接続してすぐに切断するので、接続がしばらくゼロに戻る。その時点では辛抱してほしい。接続が遅いのは初回だけだ。
これにより、TORユーザーは-addnodeを使う必要がなくなり、自動的に接続される。
Quote from: laszlo on June 14, 2010, 06:30:58 PM
使えるIRCサーバーを運用している。かなり安定しているが、冗長な接続ではない。今のところ2つのサーバーだけだが、いじったりはしない。ただ動いている。
俺のマシンは専用のIRCサーバーだ。
これは良いアイデアだと思う。
皆さんどう思うか、0.3で切り替えるべきだろうか?
Freenodeをフォールバックサーバーとして残しておいた方がいいかもしれない――彼のサーバーが動かない場合はFreenodeのを使うように。
接続するIRCサーバーとチャンネルを選択できるオプションダイアログを用意すべきかもしれない。
全員が同じIRCサーバーとチャネルに接続して、互いを見つけられるようにする必要がある。
Quote from: Vasiliev on June 25, 2010, 11:50:15 PM
Freenodeをフォールバックサーバーとして残しておいた方がいいかもしれない――彼のサーバーが動かない場合はFreenodeのを使うように。
大量のユーザーが一度にFreenodeに殺到するのはよくないかもしれない。
フォールバックは私たち独自のシードシステムだ。
irc.lfnet.orgはかなり古く、印象的なアップタイムを持っている。問題ないと思う。
いずれIRCを外すこともできるが、今のところは段階的に進めて、バックアップとして独自のシードシステムをテストしたいし、2つの異なるシステムの相補的な冗長性の特性がとても気に入っている。