ビットコイン・インスティテュート

IRCブートストラッピングについて

soultcer 2010年3月15日19:58 UTC

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を運用し、サトシまたはSiriusにURLを伝え、各リリースにリストを追加してもらう。これにより、制限的なファイアウォールやTOR環境下のユーザーも手動でノードを探すことなくビットコインを使用でき、はるかにスケーラブルなアプローチとなる。(おまけとして、whatismyip.comなどへのHTTPコールも不要になる)

もちろん、ビットコインのブートストラッピングにはもっと良いアイデアがあるかもしれないし、ぜひ聞きたい。あるいはWebcacheのアイデアへの提案でも。ぜひここに投稿してほしい!

それでは。

soultcer

セグメンテーションを排除するために、すべてのピアが他のすべてのピアのリストを持つべきだ。Torにも同じ要件があるので、Torを真似るべきだ:信頼できるディレクトリサーバーが定期的にすべてのピアの署名付きリストを作成し、HTTPで公開する。すべてのBitCoinクライアントがディレクトリミラーとして機能するオプションを持ち、それはdirServersのリストに示される。生成者はリストへの追加を依頼する必要がある(このリストにはそのピアが受け入れる最大接続数などの情報も含められる)が、単にトランザクションを行いたい人はdirMirrorからリストを取得して、いくつかのランダムなピアに接続すればいい。

これが中央集権的すぎるなら、I2Pがやったように、誰でもディレクトリサーバーになれるようにすることもできる。ただしその場合、dirServerが不正を働いた時に検出できる必要がある。

The Madhatter 2010年3月16日01:57 UTC

個人的にはI2P方式に一票だ。うまく動く。

soultcer、Freenodeのスタッフと話してくれてありがとう。現在の規模では問題ないとわかって良かったし、Freenodeに私たちの存在を知ってもらえた。TORのようなプロジェクトを支援しているので、おそらく私たちにも好意的だろう。歓迎に甘えて居座りすぎないようにしたい。もし大きくなりすぎたら、同じ理論で、もうIRCは必要ないほど大きくなっているということなので、退出する。

IRCが必要だったのは、静的IPを持つ人がいなかったからだ。初期にはいくつかの安定した支持者がいたが、全員が数日ごとに変わるプール割り当てのIPを持っていた。IRCは一時的な解決策にすぎない。ビットコインに組み込まれたaddrシステムが主な解決策だ。

ビットコインは任意のビットコインノードからIPリストを取得できる。その意味で、すべてのノードがディレクトリサーバーとして機能している。

現在のバージョンが使われなくなるまでに少なくとも1つはまだ稼働している可能性が十分にある静的IPノードが揃えば、シードリストをプリプログラムできる。

シードリストはどのようにまとめるのがいいと思う? しばらく静的だった現在接続中のIPから作成するのは大丈夫だろうか?

ちなみに、別のディレクトリサーバーソフトウェアを展開して補完したい場合、IRCを提案してもよいだろうか? IRCは良いディレクトリサーバーだ(他の用途もあると聞いている)。誰でも実行できる成熟したIRCサーバー実装が利用可能だ。ビットコインのIRCクライアント実装は既に十分にテストされている。

Xunie 2010年4月8日19:57 UTC

我々はみんなブートストラップシステムについて話しているが、私のアイデアはもう少し良いかもしれない。

ユーザーが初めてホスト上でbitcoinを起動すると、最初に接続先のノードのリストをダウンロードする。 (もちろん、bitcoinにハードコードできる静的ノードがたくさん揃うまでの話だが……) 次にクライアントは、ダウンロードしたリスト上のIPに接続を試みる。前回bitcoinを起動したときからリストを持っているなら、それらに接続する。 接続できたら、クライアントは各ノードに対して知っているノードのリストを問い合わせ、自分のノードリストを更新する。 完全なリストが取得できたら、ハードドライブに保存し、メモリーにもコピーを保持する。(これは、実際にインデックスサーバーに接続しなくてもノードのリストを持っていたいからだ。) そして最終的に、ノードは完全にネットワークに接続された状態になる。 新しいノードが接続してきたとき(「新しいノードパケット」を受信したとき)、リストはメモリー上で更新されると同時に、再びハードドライブにも保存される。 新しいノードでのリスト更新をできる限り帯域幅に優しくするため、私は各ノードがネットワークに接続してきた新しいノードのIPを、自分が知っている全ノードに「エコー」することを提案する……

利点:

  • ブートストラップを念頭に置いている。
  • ノードリストを持っているクライアントに対して分散している

欠点:

  • ブートストラップが終わるまで、新しいクライアントは新しいノードリストを取得するためにサーバーに接続する必要がある。

私の目にはこれがブートストラップ問題への最良の解決策に思える…… 追伸:もしこれを実装するなら、受け取った「新しいノードパケット」に偽のIPや.govドメインに解決されるIPが含まれていないかチェックしたくなるかもしれない! 😛

DataWraith 2010年4月30日14:51 UTC

みんな、こんにちは。

これはバカなアイデアかもしれないし、バカでなかったとしてもこの先数年は実用的ではないかもしれないが、とりあえず投げかけてみることにする:

マルチキャストはどうだろう?

IPv6はIPv4よりもマルチキャストのサポートが優れているとされている。ビットコインのプロトコルを誤解していなければ、ほとんどのメッセージはネットワーク全体にブロードキャストされる必要がある。理論的には、ノードはそうしたメッセージをグローバルなマルチキャストアドレスに送信でき、全員が帯域幅効率の良い形で受信できる。

そうすれば、クライアントはマルチキャストチャンネルを購読するだけでよくなるので、従来の意味でのブートストラップは不要になる。残る「ブロックxyzをくれ」というリクエストは、マルチキャストチャンネルへのメッセージにオプションで「私のアドレスは2001:db8::42で、特定のブロックへの直接クエリに答える用意がある」といったフィールドを含めることで処理できる。チャンネルをしばらく聴いていれば、少なくとも新しいブロックは時々そこでアナウンスされるはずなので、そういうパケットが回ってくるはずだ。

Xunie 2010年5月3日20:36 UTC

IPv6についてはあまり詳しくないが、可能ならよさそうな話だ。 ただし、現時点で世界の10分の9はまだIPv4を使っていることは忘れないでほしい! だからこれは素晴らしいアイデアだし、開発者(そういえばbitcoinには何人いるんだ?)はbitcoinに実装するべきだ(あくまで私のささやかな意見だが)。 ただし、デフォルトでIPv6を使うようにするのは良くない。

みんながIPv6を使うようになれば全く実用的だ。ただ、まだみんなIPv4を使っているというだけのことだ!

(そして今気づいたが、私は前の投稿で他の人がアドバイスしたことを基本的に説明してしまっていた……おっと!)

Cdecker 2010年6月8日12:11 UTC

ブートストラップの可用性を確保するためにFast Flux [1]ネットワークで協力する、複数のエンティティが所有するDNSサーバーのセットに興味のある人はいないかな?

[1] http://en.wikipedia.org/wiki/Fast_flux

IRCの何が問題なの? ピアリストを交換するために使われるもう一つの方法にすぎない。接続を阻止して -addnode=1.2.3.4を使い、ブートストラップ用の既知のノードに接続すればいい…

ノードがリストを取得した後にIRCから切断すると、ブートストラップしようとしているノード以外は空になるので、ブートストラップにはあまり使えなくなる。

IRCは昔からあり、十分に文書化されている(初心者にも理解しやすい)。なぜもっと複雑なものを作る必要があるの?

Gnutellaが使っているような分散型ホストキャッシュのアイデアは良いと思う。現時点では、大多数の人にとってIRCは単一障害点だ。何らかの理由でFreenodeのチャンネルがなくなったと仮定しよう。Freenodeが嫌気がさして閉鎖したのかもしれない。MenInBlackが私たちのシステムを見て狂ったように笑い、Freenodeに閉鎖するよう圧力をかけたのかもしれない。

クライアントを起動しても何も起きない。コマンドラインに移って -addnode(あるいは -peer? まあいい)とタイプして既知のノードに接続することはできるが、その時点でノードを知っている必要がある。私たちにとってはそれほど難しくないだろうが、新規ユーザーはどうか? ウェブサイトにピアリストを置くこともできるが、その時点で「キラキラした金貨をダブルクリックして取引開始」から「ウェブサイトで更新されたピアリストを確認し、コマンドプロンプトを開き、bitcoinディレクトリに移動し、正しいピアをタイプして…」になってしまう。もしMIBが追ってきているなら、ウェブサイトもとっくになくなっているだろう。

もちろん、addpeerをもっとユーザーフレンドリーに実装することもできる。「ネットワークに接続できません。ピアを入力してください:」というポップアップに、見つけ方の説明を添えて。しかしその時点で、技術的問題に対してソーシャルな解決策を作っていることになる。

また、大きくなればいずれにしてもIRCから移行する必要がある(OPのFreenodeスタッフとの会話が示唆するように)。Torユーザーはどうか? 匿名にするためにTorを使いたい人が、なぜ手動でピアを追加しなければならないのか?

最後に、Freenode上の誰でも、実行中のすべてのビットコインクライアント、いつオンラインになったか、いつオフラインになったかなどのリストを簡単に取得できる。これはプロジェクトの公言する匿名性の目標に反する。もちろん、ホストキャッシュシステムでも、そのキャッシュに接続した人はサーバーオペレーターに記録されうるが、一人のオペレーターがネットワークの全体像を把握することはない。

IRCソリューションは素晴らしい出発点であり、その安定性が証明されたことを称賛する。ネットワークを簡単に立ち上げ、プログラムのより興味深く重要な検討事項に集中するという素晴らしい判断だった。ただ、ビットコインはいつかそれを卒業すると思う。まだなら。

Bitcoinにはaddrメッセージを使った独自の分散型アドレスディレクトリがある。現在の長期稼働している静的ノードのリストをシードとしてコードに組み込む時期が来た。新しいノードがシードノードに優先的に接続し続けないようにするコードを追加できる。接続してリストを取得するだけなので、シードノードの負担にはならない。

どう思う? シードの追加を進めていいだろうか?

最初にIRCを試すことに変わりはない。IRCにはリスト上にいるために接続を維持する必要があるため、現在オンラインのノードをリストアップできるという利点があるが、単一障害点であるという欠点がある。addrシステムには単一障害点がないが、最近見られたノードしか教えてくれないため、試したノードの一部がオフラインになっているので、接続に少し時間がかかる。両方の組み合わせにより、両方の長所と、より高い全体的な堅牢性が得られる。

Freenodeが私たちにうんざりした場合に備えて、IRCサーバーを運用するボランティアをしてくれる方はいないだろうか?

使えるIRCサーバーを運用してるんだよね。かなり安定してるけど、冗長な接続とかじゃなくてさ。今のところ2台だけどさ、いじったりとかもしてなくて、ただ動いてるんだよね。

うちのマシンは専用のIRCサーバーなんだ。2:28PM up 838 days, 20:54, 1 user, load averages: 0.06, 0.08, 0.08

接続にはirc.lfnet.orgを使ってよ。

#linuxosにいるから、誰か来たいなら顔を出してくれ。

blanu 2010年6月18日05:12 UTC

これは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ミラーの数とセンチネルの数を変えることで必要なだけ堅牢にできる。

DataWraith 2010年6月18日14:08 UTC

eMuleがKADネットワークのブートストラッピングを処理する方法は、かなり最適に近いと思う:

既知のピアのリストはファイル(nodes.dat)に保存され、各クライアントがそのファイル内の既知ノードのリストを維持する(最長稼働時間でソートされていると思う――これはKademliaの固有の特性だが、それでも良いアイデアだ)。リリースされるクライアントには、静的IPアドレス上の信頼できるピアのアドレスを含むそのようなファイルが同梱されるべきで、そこから新しいクライアントが接続先のアドレスを取得できる(そして自分のファイルに保存する)。

「シードリスト」が古くなったり、サーバーがシャットダウンしたりした場合は、ネットワーク上の誰にでも自分のnodesファイルを公開してもらえばいい(たとえばrapidshareで)。ほら、接続できるIPアドレスの最新リストが手に入る。

SVNバージョンでは、まずIRCを試し、それが失敗した場合はハードコードされたシードノードのリストにフォールバックするようになった。次のリリースまでにシードノードの多くがまだ稼働しているはずだ。シードノードにはアドレスリストを取得するために一時的に接続してすぐに切断するので、接続がしばらくゼロに戻る。その時点では辛抱してほしい。接続が遅いのは初回だけだ。

これにより、TORユーザーは -addnodeを使う必要がなくなり、自動的に接続される。

ラズロ・ハニエツの投稿(2010年6月14日18:30 UTC)

使えるIRCサーバーを運用してるんだよね。かなり安定してるけど、冗長な接続とかじゃなくてさ。今のところ2台だけどさ、いじったりとかもしてなくて、ただ動いてるんだよね。

うちのマシンは専用のIRCサーバーなんだ。2:28PM up 838 days, 20:54, 1 user, load averages: 0.06, 0.08, 0.08

接続にはirc.lfnet.orgを使ってよ。

これは良いアイデアだと思う。

皆さんはどう思う? 0.3で切り替えようか?

Vasiliev 2010年6月25日23:50 UTC

Freenodeをフォールバックサーバーとして残しておいた方がいいかもしれない――彼のサーバーが動かない場合はFreenodeのを使うように。

接続するIRCサーバーとチャンネルを選べるオプションダイアログを用意したほうがいいかもしれませんね。

全員が同じIRCサーバーとチャネルに接続して、互いを見つけられるようにする必要がある。

Vasilievの投稿(2010年6月25日23:50 UTC)

Freenodeをフォールバックサーバーとして残しておいた方がいいかもしれない――彼のサーバーが動かない場合はFreenodeのを使うように。

大量のユーザーが一度にFreenodeに殺到するのはよくないかもしれない。

フォールバックは私たち独自のシードシステムだ。

irc.lfnet.orgはかなり古く、印象的なアップタイムを持っている。問題ないと思う。

いずれIRCを外すこともできるが、今のところは段階的に進めて、バックアップとして独自のシードシステムをテストしたいし、2つの異なるシステムの相補的な冗長性の特性がとても気に入っている。

torrentトラッカーに便乗するのはどうだろう? 人々がbittorrent経由でダウンロードしている時、彼らのIPアドレスはトラッカーに保持されており、接続してくる全ノードから参照可能だ。たとえば、複数の公開トラッカーで告知される小さなファイルを用意することができるかもしれない。人々がそれを「シード」している間、彼らのアドレスは初期ピアアドレスとして既知のものになり、利用可能になる。現在多くの公開トラッカーが利用可能で、それら全てが一斉にシャットダウンされる可能性はほとんどない。

今のブートストラップの仕組みはかなりうまく動いているし、需要が増えればスケールさせられる。IRCや組み込みの代替シーディングシステム経由で接続できない場合でも、-addnode=1.2.3.4で稼働中のノードのアドレスを指定すればいい。一度ノードを見つけて接続できれば、bitcoinプロトコル経由で他の全ノードのアドレスを取得できるので、ネットワークに入るためのシーディングシステムは不要になる。仮にIRCがダメでも、ここの「Static IP Address」スレッドにあるアドレスのどれかを使って最初の接続をすればいい。

PulsedMedia 2010年7月18日04:03 UTC

シードリストが長く、それらが高速で叩かれても耐えられるピアであることを願う。 十分なインセンティブが与えられれば、ルートDNSサーバーですら危険にさらされる(数年前にほとんどがDDoSで落とされた)。だからリストは長くあるべきだし、それらのノードは耐えられる必要がある。

つまりリストは最低でも1000ノードはあるべきで、そうすればDDoSされても被害があまり大きくならない。仮に平均100Mbpsや1GigEのノードだったとしても、落とすのは依然として容易だ。長期的に見て、Freenet + シードリストでは十分ではないと思う。手動で接続先ノードを追加するのは選択肢にならない(フォーラムにここで投稿された同じリストも同じように簡単にDDoSされ得る)。

最終的には10,000ノードのリストがあって、第三のフォールバックとしてbitcoinユーザーが多いと知られている動的DHCPプールのネットワーク(いくつかのISP)をランダムに試す、というのが良いかもしれない。それらに加えて静的HTTP(信頼できるボランティアが管理するもの)とDNSポインタ(同じく信頼できるボランティアが管理するもの)があれば、心配しなくて済む十分なフォールバックになるはずだ。

確かに、これは今日の問題ではない。しかしBCが成長し、その価値が上がるにつれて、ある種の人々にとってはそれを妨害する大きな関心とインセンティブが生まれるはずだ。莫大なリソースを持つ人々だ。500万ノードのボットネットが攻撃に使われた場合を考えてみてほしい……平均アウトバウンド2Mbpsだけでも、10Tbit/sの攻撃に相当する。

しかし今のところ、これで十分だ。