Ethereum と Bitcoin の違い

最近関わっている話で、(また新しいバズワードなのだけれど) blockchain という技術がある。Bitcoin で有名になった分散処理プラットフォームであるが、その OSS 実装に Ethereum というのがある。Ethereum と Bitcoin の差分はなんなの?ということでちょうど手頃な記事 を見つけたので簡単に抜粋してみた。実装を見て実機で動かしてみないと理解したことにはならないけど、取っかかりとして。

  • ブロック更新間隔が 10 分 (Bitcoin) か 12 秒 (Ethereum) かという違い
  • 長期的に採掘の reward が半減していくか (Bitcoin)、同量で維持されるか (Ethereum) という違い
  • トランザクションコストの計算法の違い、一定とするか (Bitcoin)、計算量や消費リソースで重み付けする Gas ベースか (Ethereum)
  • Ethereum は turing 完全、つまり十分な計算パワーと時間があれば、あらゆる計算が可能。Bitcoin にその柔軟性はない
  • Ethereum は crowd funded だが、Bitcoin は初期の採掘者が独占している
  • Ethereum は centralized pool mining (大規模採掘) を非推奨と考え、採掘の reward の計算に大規模採掘が有利にならない GHOST プロトコルを採用する、一言で言えば fork して主流にならず捨てられた chain 上の stale ブロックに対しても reward が与えられるため、大規模採掘で他の採掘者を無効化することができない
  • Ethereum は Ethash というハッシュアルゴリズムを用いていて、ASICS (専用 HW) を用いることの有利が起きにくいようになっている

git format-patch/send-email でベースバージョンを明示する

git が広く使われるようになって pull request の文化が広まったが、 古き良き (悪き) LKML ではレビュー依頼はメールベースで行うのが一般的である。 そこで git-send-email が活躍するのだが、 これには –src-prefix と –dst-prefix というオプションがある。 これは出力される diff のファイル名表示部、

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c  <=== これ
index c374e1e71e5f..d855ddffd5fe 100644
--- a/fs/btrfs/extent_io.c  <=== これ
+++ b/fs/btrfs/extent_io.c  <=== これ
@@ -4607,9 +4607,7 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64
start,
 {
        struct extent_buffer *eb = NULL;

-       eb = kmem_cache_zalloc(extent_buffer_cache, GFP_NOFS);
-       if (eb == NULL)
-               return NULL;
+       eb = kmem_cache_zalloc(extent_buffer_cache, GFP_NOFS|__GFP_NOFAIL);
        eb->start = start;
        eb->len = len;
        eb->fs_info = fs_info;

の先頭にくる “a/” だの “b/” だのという部分に任意の文字列を指定するものである。 パッチが与える変更には全く影響しないが、 これを用いてパッチを適用するベースバージョンを指定するという行為は 非常に意味のある行為だと思っている。

昔、LKML (linux-mm?) 的には「(明示的にバージョンを指定しない場合は) 最近のメインラインの -rc カーネルを使用する」という暗黙のルールが あるような話を聞いたことがあるが、 現実はそうなっていないし、パッチをテストしようとしてベースカーネルが 分からず (手元で当てようとしたら綺麗に当たらない)、 投稿者本人に聞くということを何度もやったことがある。 仮に当たったとしても、投稿者と同じカーネルをテストしているという保証はなく、 意味がないテストをやっている可能性が残ってしまう。 なので、個人的に git-send-email で投稿する場合は

diff --git v4.2-rc4/fs/proc/task_mmu.c v4.2-rc4.patched/fs/proc/task_mmu.c
index ca1e091881d4..c7218603306d 100644
--- v4.2-rc4/fs/proc/task_mmu.c
+++ v4.2-rc4.patched/fs/proc/task_mmu.c
...

みたいに明示的に指定することを推奨した方がよいと思っている。

ベースカーネルをディスクリプションや 0 番パッチに書く手もあるが リベースしたら編集しないといけなくて面倒だし、 マージ後にディスクリプションに残す必要がない情報なので、 あまり良い方法ではないと思う。 あと、subject に “[PATCH mmotm]” などと指定して大雑把にベースカーネルを 示す方法もあるが (これはこれで否定しないが)、 正確なバージョンを指定するには文字数が必要になってきて subject に 入りきらないため、ちょっと弱い。

というわけで、もしその方面で (自分の中で) 盛り上がったら、 scripts/checkpatch.pl にこれを warn する変更を提案してみたいところである。

いくつか tips。

–src/dst-prefix に渡す文字列は git-describe を用いて生成するのが楽である。 git-send-email を直接コマンドから打つと送信ミスしやすく、 大抵の人は何らかのラッパーを書くと思うので、単にそこに数行仕込むだけで済む。

あと、ありがちなミスとして –src-prefix を使用するときは安直に –src-prefix=v4.2-rc4 などと指定してはいけない。 これだと diff が

diff --git v4.2-rc4fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index ca1e091881d4..c7218603306d 100644
--- v4.2-rc4fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c

みたいになり、’/’ が足りず不正なファイルパスを指定することになって パッチが当たらなくなるためである。 私は過去に一度これをやってしまって akpm に怒られたことがある。 末尾に ‘/’ を付けるのを忘れてはいけない。