Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoin Core 0.14.0のリリース

Bitcoin Core 0.14.0がリリースされたのでどんな変更があったのか見ておく↓

Bitcoin Core :: Bitcoin Core 0.14.0 Released with Performance Improvements

主な新機能は↓

IBDのパフォーマンス改善

ブロックチェーンのデータサイズは絶えず増加していて、現在mainnetのデータ量は125GBと巨大。新しくノードを立ち上げる場合、最初に大量のブロックデータをダウンロードして処理する必要がありウォレットが利用可能になるまで結構な時間がかかる。この初期ブロックのダウンロード(IBD)時間を改善するため今までいろんな改良が加えられてきた↓

リリース IBDに関する改善
0.5.0 チェックポイントより前の署名のスキップ
0.8.0 LevelDBへの切り替えと署名検証の並列化
0.10.0 ヘッダを先に同期し、その後ブロックを並列ダウンロード
0.11.0 (オプション)ディスクスペースを節約するためのブロックファイルの剪定
0.12.0 楕円曲線のライブラリを独自実装(libsecp256k1)し署名検証を高速化
0.13.1 将来古い署名のダウンロードをスキップできるようにするSegwitの導入

今回の0.14.0のリリースではこのIBDの速度を大幅に向上させる2つの改善点が含まれている↓

  1. Assumed valid blocks
  2. mempoolとUTXOのDBキャッシュ間のメモリ共有

この結果、EC2のt2.xlarge(4コア、メモリ16GB)で、Bitcoin Core 0.13.2とBitcoin Core 0.14.0で同じ設定で初期ブロックのダウンロード行うと

  • Bitcoin Core 0.13.2だと、全ブロックダウンロードが終わるのに1日と12時間40分
  • Bitcoin Core 0.14.0だと、全ブロックダウンロードが終わるのに6時間25分

と5.7倍高速化してる。

ちなみに↑はデフォルト設定の場合で、起動オプションの1つである-dbcacheオプション(デフォルト300(MB))を-dbcache=8000(8GB)を指定して実行すると約3時間で同期ができる。

で2つの改善点がどういうものかというと

Assumed valid blocks

0.3.2でチェックポイントと呼ばれる仕組みが導入された。これはフルノードに、ある時点でベストチェーンとは別のチェーンを検証させ無駄な負荷をかけるようなDoS攻撃を防ぐためのもの。

0.5.0では最新のチェックポイントより前のブロックの署名をスキップすることでIBDを高速化した。

しばらくしてBitcoinのセキュリティの改善やその他の改善(ヘッダの初期同期やminimum chainworkなど)によりチェックポイントの必要性は減り、チェックポイントは既に有効だと判断したチェーンのみを受け入れるものではあるが、どのチェーンが有効か判定しているように見えセキュリティモデルについて開発者の混乱を招くおそれがあったので、多数の開発者からチェックポイントを削除したいという要望が出た。

Assumed valid blockは、署名スキップの最適化処理をDoSを防ぐためのチェックポイントから分離し、それぞれ独立して実行できるようにした新機能になる。

どういうものかというと、フルノードを新規に起動する際、そのユーザが有効なブロックを知っている場合、その有効な最新ブロックのブロックハッシュをBitcoin Core 0.14.0に渡すことで、そのブロックの前までの署名をスキップする機能になる。署名の検証処理はIBDの処理の中でもCPU消費が大きいためAssumed valid blockを使うとIBDを大幅に高速化できる。指定したAssumed valid block以降のブロックについては、全てちゃんと署名が検証される。

チェックポイントとAssumed valid blockの大きな違いは、チェックポイントに指定されているブロックはブロックチェーンの一部でないといけないけど、Assumed valid blockは別にチェーンの一部でなくても良い。ユーザーから渡されたAssumed valid blockがチェーンの一部でない場合、Bitcoin Coreは単純に全ての履歴ブロックの署名を検証するだけ。また、フォークが発生し最新のPoWの結果有効なチェーンにAssumed valid blockで指定したブロックが無い場合、Bitcoin CoreはAssumed valid blockを破棄して新しい有効なチェーンに切り替える。

これからBitcoinを始めようというユーザーは、おそらく有効なブロックとか知らないと思うけど、全てのコンセンサスルールを知っているとも思えないので、そういったユーザーは単純にフルノードをダウンロードして使えば良い。Bitcoin Core 0.14.0には複数の著名な開発者がそれぞれ有効であると確認したデフォルトのAssumed valid blockが組み込まれている↓

  • mainnet(#453354)
    00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90
  • testnet(#1079274)
    00000000000128796ee387cf110ccb9d2f36cffaf7f73079c995377c65ac0dcc

Assumed valid blockを使わずに全ての署名を検証したい場合は、-assumevalid=0をオプションにつけて起動すればいい。任意のAssumed valid blockを指定する際は以下のようにassumevalidで対象ブロックのブロックハッシュを指定する。

-assumevalid=00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90

mempoolとUTXOのDBキャッシュ間のメモリ共有

IBDの処理中は、Bitcoin Coreはmempoolを使用しない。これは最新のブロックが無いと最新のトランザクションが有効化どうか確認する方法が無いためで、その間通常よりもメモリ消費は少ない。

0.14.0では、このIBD中に使われていないmempoolのメモリをUTXOデータベースキャッシュと共有するようになる。これによりより多くのUTXOを高速なメモリ上にキャッシュできるようになり、ディスクアクセスを減らすことができる。

新しいブロックの検証とリレーの高速化

0.14.0の↓の4つの改善点は、新しいブロックをできるだけ速く受信したいマイナーやその他のユーザーにとって特に関心があるものになる。

署名キャッシュの改善

最初の機能はcuckoo hashingを使うための署名キャッシュの更新。署名キャッシュはBitcoin Coreが未確認のトランザクションの署名の検証結果をキャッシュできるようにするもので、同じトランザクションが新しいブロックに含まれていた場合に再度署名を検証しなくてすむ。署名の検証は新しいブロックを処理する際に計算コストが最も高い処理なので、署名キャッシュを使うと新しいブロックを処理する速度が大幅に向上する。

既存の0.13.2の署名キャッシュは、CPUが8コア未満であれば上手く機能するけど、8コア以上のCPUを持つ場合、ロックが発生し使用可能なコアを有効活用できない。“cuckoo cache”を利用できるようcuckoo hashingを使用するようアップグレードすると、この問題は解決され、より多くのコアを効果的に利用できるようになる。

16コアの環境でテストすると、0.14.0を使うと0.13.2より40%速く新しいブロックの処理が可能になった。8コア未満の環境では大幅なパフォーマンスの向上は無いけど、同じメモリ量で以前より多くの署名をキャッシュすることができる。

以前のBIP152のCompact Blockリレー

2つめの改善点は、 BIP152のCompact Blockの実装。以前の実装ではBIP-152の2つのオプトインモードがサポートされていた↓

  • 帯域幅モード
    新しいブロックをリレーするのに必要最小限のデータ送信するモードで、受信ノードが特定の新しいブロックの要求を待つ
  • 帯域幅モード
    受信ノードによる特定の新しいブロックの要求を待つこと無く、新しいブロックデータを送信するモード。この場合、受信ノードが既に別ノードから受信したデータと重複するデータを送信するリスクはあるが、ブロックは迅速に転送される。

0.14.2で更新された実装では、ブロックが完全に検証される前に新しいブロックのリレーを始めることで、高帯域幅モードのノードを強化する。最良の場合、検証遅延が無くなることで新しいブロックがP2Pネットワーク上で数ホップに渡って以前より数倍速くブロックを伝播させることができる。最悪の無効なブロックの伝播で余計な帯域幅を消費する。いずれの場合も無効なブロックは受信側のノードで拒否されるのでセキュリティモデルは今までのまま。

※ BIP-152の仕様については↓

techmedia-think.hatenablog.com

並行性とスループットにフォーカスしたP2Pコードのリファクタリング

3つめの改善点は並行性とスループット向上のためのP2Pネットワークコード全体のリファクタリング。並行性の改善では、新しく受信したブロックを優先度の低いトラフィックよりも先に処理できるようになり、ブロックができるだけ速くリレーされ検証できるようになる。

またメッセージの処理中にバックグラウンドでネットワーク処理も継続して行えるようになり、特にIBDの速度の改善にも繋がる。

mempoolをディスクに保存

4つめの改善点は、各ノードが受信した未確認のトランザクションのmempoolが通常のシャットダウン時にディスクに保存され、ノードが再び起動した際にディスクからメモリ上にロードされるようになった。

Compact Blockと組み合わせることで、未確認のトランザクションが新しく生成されたブロックに含まれている際、再ダウンロードする必要がなくなる。署名キャッシュと組み合わせることで、未確認トランザクションの署名の検証結果のキャッシュで、新しいブロックをより迅速に検証することができる。

こういった機能はよくRDBがシャットダウン時にキャッシュをディスクに保存して、次回起動時にそこからキャッシュを復元しウォームアップ期間を短縮するのに使われるテクニックと似てる。

(オプション)手数料の置換

0.14.0のオプション機能(デフォルトは無効)として、ウォレットで前に作成したトランザクションを新しく生成したトランザクションで置換する機能が含まれ、これによりBIP-125のオプトインReplace By Fee が利用可能になる。

Bitcoin Core起動時に-walletrbfオプションを付与してこの機能を有効にすると、作成したけどまだ承認されていないトランザクションについて、より高い手数料を設定して再送信することができるbumpfee RPCが利用できるようになる。オプトインRBFもしくはフルRBFをサポートするマイナーは、手数料の低いトランザクションから高くなったトランザクションにキューのデータを置換する。手数料が高くなった分マイナーにはより速くブロックに入れるインセンティブが働く。