この記事はBlockchain Advent Calendar 2019の18日目の記事です。
ハードフォークのタイミング
BitcoinやEthereumではハードフォークやソフトフォークでなにかスペックを変える際に、事前に決めたブロック高を発動タイミングとしています。たとえばBitcoinでSegwitがアクティベートされたのは高さ481,824、先日のEthereum Istanbulハードフォークは高さ9,069,000、といった具合です。
では、ブロックチェーンが特定の高さに達する時刻はどのように予測したらよいでしょうか。すぐに思いつくのは、ブロック生成間隔(Bitcoinなら10分くらい、Ethereumなら15秒くらい)に幅をもたせて、残りブロック数をかける方法ですが、この記事ではよりカッコよく確率モデルを使って考察・実験をしてみました。
確率モデルを考える
ブロック生成間隔がある平均をもっていて、そのばらつきがランダムであると仮定すると、ブロック生成間隔は指数分布に従う1といえます。
ブロック生成間隔を指数分布に従う確率変数X_i
とおいて、N
個先のブロックが生成されるまでにかかる時間を確率変数X
とおくと
X = \sum^{N} X_i
物の本によると2、指数分布に従う確率変数の和はアーラン分布に従うことが知られているらしいので
P( a < X < b) = \int_a^b f(x) dx
f(x) = 1-e^{-\lambda x} \sum_{n=0}^{k-1} \frac{(\lambda x)^n}{n!}\ ...\ (式1)
X
の値を予測するにあたっては範囲を考えて、その範囲にたとえば80%の確率で入るようにすることを考えます。これは台風の予報円3と同じ考え方です。そのためには式1で示した確率密度関数f(x)
の10%点・90%点をもとめればよさそうです。
やってみた
scipyを使って、BitcoinのSegwitの時を例に実際にやってみました。scipyのstatsパッケージにはアーラン分布の関数群4が実装されているので、簡単に計算する事ができます。ここではSegwitがアクティベートされる1,440ブロック前を起点として、アクティベートのタイミングを予測してみましょう。
> from scipy.stats import erlang
> from datetime import datetime
> t0 = 1502643810 # 高さ (481,824 - 1,440 = 480,384) のブロックのタイムスタンプ
> t1 = t0 + erlang.ppf(0.1, a=1440, scale=600) # 10%点
> t2 = t0 + erlang.ppf(0.9, a=1440, scale=600) # 90%点
> datetime.fromtimestamp(t1).isoformat()
'2017-08-23T17:59:22.611067'
> datetime.fromtimestamp(t2).isoformat()
'2017-08-24T10:11:54.335005'
では、答え合わせをしてみましょう → こちら
...ハズレました! 😞
考察
実際のブロック生成間隔を測ると、Segwitアクティベート前は9分程度で推移していて想定している平均値になっていないことがわかります。このモデル化の参考にした記事1でも、マイニングに関わる恣意的な要素によってモデルがうまくフィットしないことが示されています。
なお、この記事の実験でSegwitを取り上げたのは、事前にEthereum Istanbulハードフォークでやったところ大外ししてしまい、Bitcoinならうまくいくのでは?と期待したためだったりします。Ethereumの場合はディフィカルティボム5の関係で、よりモデル化しづらい事情があります。