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

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

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

よろしく、 soultcer

theymos 2010年3月16日 01:28 UTC 原文 ·

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

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

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

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

soultcer、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 から切断すると、ブートストラップしようとしているノード以外は空になるので、ブートストラップには使えなくなる。

lachesis 2010年6月8日 13:57 UTC 原文 ·

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 サーバーだ。

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日 09:30 UTC)

使えるIRCサーバーを運用している。かなり安定しているが、冗長な接続ではない。今のところ2つのサーバーだけだが、いじったりはしない。ただ動いている。

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

皆さんどう思うか、0.3 で切り替えるべきだろうか?

Vasiliev 2010年6月25日 23:50 UTC 原文 ·

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

接続する IRC サーバーとチャンネルを選択できるオプションダイアログを用意すべきかもしれない。

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

Vasilievの投稿(2010年6月25日 14: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 の攻撃に相当する。

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