[翻訳] GitTorrentを発表 - 分散型GitHub -


ヤク中

この投稿はChris Ball氏による次の投稿を翻訳したものです。

Chris Ball » Announcing GitTorrent: A Decentralized GitHub

すべての権利は彼に帰属します。あと私はまだ大学生なのでちょっと翻訳が汚いです。 原文より口調が強いといったこともあるかもしれません。まあこまけえことは気にせず読みな!

本文

(この投稿は2015年の5月にData Terra Nemoのカンファレンスで行ったトーク の意欲に溢れた原稿です。私が実際に行ったものと同じトークをよりゆっくりと話したものの動画が 近いうちに公開されます。)

私は分散型GitHubの構築に取り組んでいるのですが、このことが何を意味し、なぜ重要なのかという ことについて、そしてもっと重要なことである、それがどのようにして成され、これまでに実装してきた GitTorrentの本当のコードがどうなっているのかをここでお見せしたいと思います。

なぜ分散型GitHubを?

まず、実際問題として、GitHubはハックされたりして信頼できなくなるかもしれないということがあり ます。あるいは―私がこのプロジェクトに取り組んでいるときに起こった 中国によるDDOS を受けるなんてこともあるかもしれません。その瞬間からGitHubが多くの対応を行ってくれているよう であることを知っていましたが、ベンチャーキャピタル投資によって1億ドルの資金を得た会社が使用者 の意思に強く反する決定をし始めることはしばしばあることなのです。

信条に関する理由もあります。GitHubはクローズドソースであり、私たち自身によってそれをより良くする ことはできません。Mako Hillはフリーソフトウェアを制作するにあたって プロプライエタリ・ソフトウェアに依存する際の問題を Free Software Needs Free Tools というエッセイに書いています。私は彼のいうことはもっともだと感じています。他の言い方もできる でしょう。オープンソースプロジェクトを取り巻く私達の共同作業はGitHubが決めた改変不可能な ツールによって制限されてしまっているのです。

これらが実際問題と信条における理由です。3つ目の理由は「皮肉」とでも呼びましょうか。CVSや Subversionプロトコルを利用した多くのサーバーから分散型であるGitプロトコルによる対話を行う ひとつの集中サーバーに移行したというのは大きな皮肉でしょう。Google Codeは数か月前に 終了を発表しました。 その根拠には「みんな気にせずGitHubを使っているから、もう僕はいらないんだよね」といったことが あるのは明白です。私達はあっという間にひとつの集中型サービスに世界中のソースコードを向かわせ るようになってしまったということです。

そういったことを踏まえ、特にこのカンファレンスでは、このレベルの集中が浅はかなことであるという ことに関して私に同意してくれるものとします。

Gitはすでに分散型ではないのか?

GitHubは集中型である一方で、Gitプロトコルは分散型ではないか、リポジトリをクローンすれば そのコピーは他の人と同じにになる。それで十分じゃないか?そう考えているかもしれません。

私はそうは思いません。FTPがあるからBitTorrentなしでもやっていけるというのを想像してみて ください。別にBitTorrentをFTPで置き換えようというのでもありませんし、全く意味のないことでは ないですか?まず―どのホストがFTPでどのファイルを共有しているのか示すインデックスはありません。 そのためどこを探せばよいのかわからなくなります。次に―たとえ欲しがっているコピーを誰が 持っているかわかっていても、こういったコンピューターは匿名FTPサーバーを動かそうとするような ことはありあせん。

ちょうどGitと同じように、FTPはP2Pプロトコルがするような、クライアントをサーバーに変えるような ことはしません。これがGitが既にGitHubを分散しているとは言えない理由です。どこに何がある のか知ることはできませんし、仮に出来たとしても、そういったコンピューターはあなたが対話できる Gitサーバーを実行してはいません。私はこの状況は改善できると考えます。

リポジトリをGitTorrentしよう!

GitTorrentのデモでGitTorrentの世界に飛び込んでみましょう。次の例では、BitTorrentで ホストされているGitリポジトリをクローンします。

λ git clone gittorrent://github.com/cjb/recursers
Cloning into 'recursers'...

Okay, we want to get: 5fbfea8de70ddc686dafdd24b690893f98eb9475

Adding swarm peer: 192.34.86.36:30000

Downloading git pack with infohash: 9d98510a9fee5d3f603e08dcb565f0675bd4b6a2

Receiving objects: 100% (47/47), 11.47 KiB | 0 bytes/s, done.
Resolving deltas: 100% (10/10), done.
Checking connectivity... done.

皆さん!たった今BitTorrentでGitリポジトリをクローンしました!それでは、行ごとにこれを追って 見てみましょう。

1-2行目: Gitは実際に、内蔵されているネットワーク・プロトコルを拡張する仕組みを持ってい ます。これは私のgit cloneコマンドを「git-remote-gittorrentコマンドを実行しURLを引数 として渡す」と読み替えることで実現されます。つまり実際のダウンロードをしたいようにすることができ、 gitオブジェクトを新しいディレクトリに書き込みGitに終わったことを教えることになります。これを 作るのにGitを弄る必要は全くありません。

ここからgit-remote-gittorrentが仕事を引き受けます。まずGitHubに接続してこのリポジトリの 最新のリビジョンを突き止め、何が必要なのか理解します。GitHubは5fbfea8de..と教えて くれます。

4-6行目: それからBitTorrentと同じようにハッシュテーブルが配布されているGitTorrent ネットワークに乗り出し、誰か5fbdea8de..コミットのコピーを持っていないか聞きます。誰かが Yes!と答えました。彼らとBitTorrent接続を行います。BitTorrentの配布ハッシュテーブルは こんな感じに欲しがっているコンテンツを誰が送信できるか教えてくれるget_nodes(hash)という 一つの処理を行うことによって利用することができます。

get_nodes('5fbfea8de70ddc686dafdd24b690893f98eb9475') =
  [192.34.86.36:30000, ...]

さて、標準のBitTorrentで"trackless torrents"を行う際には、コンテンツとしてほしいファイル を要求し、そして手に入れることができればめでたしめでたしということなんですが、Linuxカーネルの サイズのリポジトリでは400万コミットあり、たった一つのコミット5fbdea8de..を受け取るだけでは 役に立ちません。更にコミットごとに400万個のリクエストを発行する必要もあります。さもなくば 'git pull'する度に1コミットずつ手に入れることになってしまいます。そこで、他の手段が必要に なるというわけです。

8-12行目: Gitはこの問題を解決します。Gitはgitオブジェクトの交換のネゴシエーションの ために"smart protocol format"を持っています。これは次のように考えることができます。

リポジトリに1から20の20コミットがあると考えてください。15番目のコミットはbbbbで最新の20番目 のコミットはaaaです。Gitプロトコルのネゴシエーションはこんな感じに見えるはずです。

1> have aaaa
2> want aaaa
2> have bbbb

git graphの仕組みにより、ここではノード1>がbbbbを探すことができます。5コミットを要求している だけなので、それらのみの"packfile"を作成しているのに注目してください。たった3段階の対話です。

以上が今回GitTorrentでしたことです。欲しいコミットを探してBitTorrentでノードとつなぎますが、 一旦接続されれば、BitTorrent Extensionと呼ばれるBitTorrentプロトコルの最上層にある オーバレイに施されたSmart Protocolネゴシエーションを実施することができます。それから リモートノードはパックファイルを作成しそのパックファイルのハッシュを伝えてくれます。そして パックファイルのダウンロードをそのノードや標準のBitTorrentを利用してシードしている他のノード からダウンロードします。展開したあとGitコミットのグラフが終わるはずの地点で終わっているか 調べることにより、packfileを認証することができます。もしそこで終わってなかったら他のノードが 嘘をついたことになるので、その代わりに誰かまた他のノードと対話を試みます。

これがさっきこの端末で起こったことの全てです。そのハッシュ値を持つ、つまり最新のすべての オブジェクトを含んでいるpackfileを得ることが出来ました。ダウンロードして展開し、そして今、 ここにローカルのGitリポジトリがあるわけです。

このgit cloneによって通常のGitHubのやり方で行われているようにgitオブジェクトの実際の ダウンロードを行うためにすべきことをすべて行います。もしGitHubが明日ディスクと帯域幅の 仕事をダルい仕事だと結論づけてしまっても、ユーザーにGitTorrentバージョンを実行するように 呼びかけることができます。これはGitHub用のP2Pコンテンツデリバリネットワーク (訳注: CDN)を 構築するようなもので、現在CDNにほしいコミットがない場合はGitHubのサーバーに フォールバックします。

本当に分散されたのか?

ある程度は分散できました。しかし最終的に狙っているもののハッシュを見つけるためGitHubに 対話したのが正に最初にしたことであることに気づいた人もいるでしょう。もし本当にGitHubを 分散化しようとするなら、それよりより良い方法、すなわちリポジトリの所有者にそのリポジトリの 最新版のハッシュが何か教える方法が必要となります。端的に言えば、私達は今ダウンロードできる gitオブジェクトのデータベースを持っているのですが、どのオブジェクトが欲しいのか知る必要がある のです。GitHubのユーザー/リポジトリにある部分をエミュレートし、ユーザーのリポジトリの正に 最新版を受け取っていることを知る必要があるのです。

じゃあ、なんとか良くしてみましょう。ハンマーがあったら何でも釘に見えますよね。私のハンマーは 配布されたハッシュテーブルで、どのコミットをどのノードが持っているか追跡するために作りました。 つい最近、subtrackがそれぞれのノードにネットワーク全体で共有され るキー・値の保持の一部分を行わせることができるBitTorrent拡張があることに気づき、コードを 書き上げました。DHTにget()put()という2つの動作を付け加えました。put()はキーごとに 1000バイトのメッセージをネットワークに置くことができ、そのメッセージは後に参照され、ネットワーク から離れたあとも他のノードによって繰り返されます。2種類のキーがあり、一つはイミュータブルキーで、 ご想像通り、登録したいデータのハッシュをとるだけで、データはキーとなるハッシュとともに保存する ことができます。

2つ目の種類の鍵はミュータブルキーで、この種類のキーではキーペアの公開鍵のハッシュを見つけられ ます。キーペアの所有者は値をその鍵で署名付きのアップデートを公開することができます。 アップデートは連続した数値が割り振られるので、クライアントは既に記録されている番号より新しい 番号のアップデートを確認することで、いつでも一つのミュータブルキーに対し一つのアップデートを 見ることができます。そしてアップデートがハッシュテーブルキーに対応する公開鍵で署名されている ことを確認することにより、キーの所有者からアップデートが来たことを証明できます。もしそれらの 条件を満たせばその新しい値で更新して再配信を開始します。これには様々な利用方法がありますが、 私の場合リポジトリがなんと呼ばれ最新版がなんであるかを保存する場所として用います。つまり ローカルなGitコミットを作成して、そのネットワークにプッシュしてから、個人用ミュータブルキーに アップデートをプッシュして新しいコミットがあることを反映させます。新しい処理のコードによる説明を お見せしましょう。

// Immutable key put
hash(value) = put({
  value: 'some data'
})

// Mutable key put
hash(key) = put({
  value: 'some data',
  key: key,
  seq: n
})

// Get
value = get(hash)

もうGitTorrent上のGitHubリポジトリをクローンするように誰かに言おうと思っても、github.comの URLを渡すことはありません。代わりに私の公開鍵のハッシュである長い16進数値を渡します。これは 配布されたハッシュテーブルのミュータブルキーとして使われます。そのデモをお見せします。

λ git clone gittorrent://81e24205d4bac8496d3e13282c90ead5045f09ea/recursers

Cloning into 'recursers'...

Mutable key 81e24205d4bac8496d3e13282c90ead5045f09ea returned:
name:         Chris Ball
email:        chris@printf.net
repositories: 
  recursers: 
    master: 5fbfea8de70ddc686dafdd24b690893f98eb9475

Okay, we want to get: 5fbfea8de70ddc686dafdd24b690893f98eb9475

Adding swarm peer: 192.34.86.36:30000

Downloading git pack with infohash: 9d98510a9fee5d3f603e08dcb565f0675bd4b6a2

Receiving objects: 100% (47/47), 11.47 KiB | 0 bytes/s, done.
Resolving deltas: 100% (10/10), done.
Checking connectivity... done.

このデモではまたGitリポジトリをBitTorrentを介してクローンしましたが、配布された ハッシュテーブルをを代わりに求めることによって探しているコミットを見つけることができたので GitHubと全く対話する必要がありませんでした。正にGitダウンロードの真の分散化が達成された のです!

最後の不満点は、16進数の長い文字列は便利なユーザー名にはなってくれないということです。 私達は確かに信用できるハッシュテーブルの頒布によって達成できることの限りに直面しています。 これはユーザー名が争奪されうる、つまり2人の異なる人が同じユーザー名の所有を主張する アップデートを提出しうるということです。2人の論争を解決する方法はありません。ユーザー名を与え、 誰がその所有者なのか理解するため、「合意の共有」を行う方法が必要です。私が見つけたもっとも 信頼できる方法は実はBitcoinの blockchain です。合意の共有が暗号通貨を可能にするのです。

Bitcoin取引の種類の一つとして、 (OP_RETURNトランザクション)[http://blog.coinprism.com/2015/02/11/80-bytes-op-return/] というものがあり、ある財布から他の財布にお金を移す代わりに、blockchainに永遠に記録される 取引のコメントを残します。最近まで取引ごとに40バイトのコメントに制限されていましたが、 Bitcoin Core 0.11によって 80バイトまで引き上げられました。 blockchain上のどんなBitcoin取引も現在は約0.08米ドルかかるはずなので、blockchainを 80バイトのデータで汚染する代わりにマイナーとネットワークにに8セント支払うのです。

もしblockchainにコメントを残せるのなら、「やあ、ユーザー名はChrisを使いたいんだ。僕の公開鍵の ハッシュは<x>だよ」なんていうコメントも残せます。もし複数の人が同じユーザー名を要求したら、 blockchainは完全な履歴を誰でも見ることができる登録専用のデータ構造なので、今度は最初に 要求したユーザーの公開鍵の使用に同意します。これがBitcoinの本当の美しさです。この通貨関連 と言ったものは率直に言って私には面白くないものですが、強固な方法で合意の共有を解決する方法を 見つけ出しました。取引のコメントはこんな感じになるかもしれません。

@gittorrent!cjb!81e24205d4bac8496d3e13282c90ead5045f09ea

(@service!username!pubkey)

通貨関連は面白くないと言いましたが、これは面白そうです。最初にある"gittorent"は別になくても 全く問題ないかもしれません。もしかしたらこれはBitcoinでによる分散型ユーザーアカウントに興味が ある全てのサイトにこの方法でユーザー名を登録することができるかもしれませんし、それからそれらの サイトの全てのユーザー名を既に得ていることになるのです。これは別のモジュール、やソフトウェア プロジェクトで実装されるかもしれません。ユーザーアカウントを取得するために分散型アプリにそれらを 導入すれば、PythonやNode、Goと言ったあらゆる言語で動かすことができるでしょう。blockchainを 監視してデータベースに書き込むアプリとデータベースを解釈する、Webやネットワークサービスの フレームワークへのプラグインで構成されることになるかもしれません。

驚きなのはこのような仕組みは分散型コミュニティで現在存在しないということです。このような プロジェクトに取り組むことができ、またその最上位にGitTorrentを据えることができ嬉しく思います。 興味がある方がいらっしゃれば、ぜひ教えていただきたいと思います。

ところで、ユーザー名の登録は私がさっき言ったよりはちょっと複雑になります。なぜならマイナーは メッセージを見て、blockchainに追加する前にあなたのユーザー名を、あなたのものとしてではなく、 彼らのものとして登録できてしまうからです。これはドメイン名登録と同じで、欲しいドメインが 利用可能か調べるために検索ボックスに入力すると、その瞬間にそのドメインを登録業者が 彼ら地震のものとして登録し、それからあなたに10万支払えというわけです。これはよくありません。

これを気にする方のために、Bitcoinは2段階の登録による回避策を持っています。最初のメッセージ ではユーザー名のハッシュのみを提出し、ユーザー名を予約するように要求します。マイナーは ハッシュからユーザー名を知ることはできませんので、あなたを先回りすることはできません。もし 予約がブロックチェインに登録され、先に他に誰も予約をしていなかったら、「よし、じゃあ予約トークンを 使わせてもらおう。予約したユーザー名はこれだよ。」といった2つ目のコメントを送信します。これで あなたのものになりました。

(私がこの方法を発明したわけではありません。これはJeremie Miller 氏によるBlocknameというプロジェクトで、これは、 bitcoinのblockchainへのDNS登録のためのOP_RETIRNトランザクションを用いて、正にこの方法 を実装します。唯一の違いはBlocknameがドメイン名登録を行うという点で、私の場合ユーザー名から 公開鍵のハッシュに割り当てました。かなり似たものとして Blockstoreがあるという指摘も受けました。)

要約すると、GitオブジェクトのグローバルなBitTorrent swarmを作成し、ユーザーアカウント登録に 取り組みました。そのため、ユーザーの実体験はこんな風になるでしょう。

これが

git clone gittorrent://github.com/cjb/foo

こうなって、

git clone gittorrent://81e24205d4bac8496d3e13282c90ead5045f09ea/foo

こうなります。

git clone gittorrent://cjb/foo

この時点でGitHubの主な機能である、Gitリポジトリを探し、ダウンロードする、分散型の代替を 達成したことになります。

最後に

まだもっとすべきことがたくさんあります。例えば、コメントやIssue、Pull Requestといったどれも GitHubにはとても重要な側面を欠いています。

私が気に入っているこの問題の解決策は、コードリポジトリ内に問題をファイルとして実際に登録する というものです。これによりブランチをマージすることでコードの変更とIssuの変更、例えばIssueの 解決といったことの両方をそのブランチにマージできるということです。このアイデアの実装の一つ としてBugs Everywhereがあります。

分散型ネットワークの追記専用のメッセージストリームを同期する Secure Scuttlebutt上でのIssueや Pull Requestの運用も考えられます。

ですが、私はここまでこれただけで十分幸せです。この設計についてみなさんの意見を聞いてみたいと 思います。GitTorrent自体の設計は(十分皮肉なことですが) GitHub上にあります。 どんな改善点でもPull Requestは大歓迎です。

あなた方のうち数人には感謝しなければなりません。まずは私がここで使っているBitTorrent ライブラリを書いてくださったFeross Aboukhadijeh氏にです。彼の P2Pとへの情熱と彼の「マッド・サイエンス」なプロジェクトに携わる人々のコミュニティに、私は とてもワクワクしましたし、私の貢献も歓迎してもらえました。これは私がこのプロジェクトに取り組む ようになった理由の一つでもあります。

またニューヨーク市のRecurse Centerに出席する間、仕事を 休むことができるため、このプロジェクトに取り組むことができています。これは"Hacker School"と かつて呼ばれていた場所で、最近 その名前を変えました。 その第一の理由は人々がものを教わるという学校の言外の意味を取り除くことです。3か月の プロジェクトを通してプログラミング能力を向上させるプログラマーにとっての隠れ家と言いったほうが より本来の姿に近いでしょう。出席することを許してくださった彼らに本当に感謝しています。

彼らが名前を変えようと決めた2つ目の理由はアメリカの国境で「ハッカースクールに行くために来ま した!」と言って…つまらない時間を過ごす羽目になってしまう海外からの出席者が続出したからです。

最後に、なぜ私がこの種の仕事が面白く、また重要だと考えているかについていくつか言葉を述べて 終わりたいと思います。プロジェクトには特定の大きさ、幅広さがあります。GitHubやWikipediaを その例としましょう。大きなデータセンターでディスクや帯域幅を保持するためにGitHubやWikipediaの ように何千万ドルを稼ぐこと以外に、有名になったあと世界規模でプロジェクトを存続させるための 方法はありません。これにより、運営のため1年に何千万ドル稼ぐためにビジネスプランを作ることが できる規模のプロジェクトしか制作したり想像したりできなくなってしまいます。分散とP2Pアルゴリズムに よって、そのような規模の投資がなくてもお互いに助け合い、共有することのできるユーザーさえいれば 夢のあるソフトウェアを作ることを考えられるようになることを願っています。

この度は聞いてくださり本当にありがとうございました。

(GitHub上のGitTorrentを確認したり それについてHacker Newsで議論 できます。また、Twitterでは私をフォローできます。)

[top]