ジェネレーションハッシュ・難易度・ターゲット・ヒット・インポータンス・チェーンスコア（Elephant 2）

# はじめに

Elephant 2 のもの

定数値はこちらを参考にしてます。https://github.com/nemtech/catapult-server/blob/v0.6.0.1/resources/config-network.properties

# ジェネレーションハッシュ

とあるブロックのジェネレーションハッシュ`h`は、その前のブロックのジェネレーションハッシュと、そのブロックの署名者の公開鍵を結合した値をハッシュしたものになります。

https://github.com/nemtech/catapult-server/blob/v0.6.0.1/src/catapult/model/BlockUtils.cpp#L50

```math
h = \textrm{Hash}(\textrm{previousGenerationHash} + \textrm{signerPublicKey})
```

# 難易度

過去`n`ブロックを用いて新しいブロックの難易度を算出する式です。

https://github.com/nemtech/catapult-server/blob/v0.6.0.1/src/catapult/chain/BlockDifficultyScorer.cpp#L26

```math
\begin{align}
d &= \frac{1}{n} \sum^n_{i=1}(\textrm{difficulty}_i) \\
t &= \frac{1}{n-1} ( \textrm{timestamp}_{n} - \textrm{timestamp}_{1} ) \\
\textrm{difficulty} &= d * \frac{g}{t} 
\end{align}
```

```math
n = \textrm{maxDifficultyBlocks} = 60 \\
g = \textrm{blockGenerationTargetTimeMillis} = 15,000
```

- `timestamp`はミリ秒です。
- ネメシスブロックの難易度は$10^{14}$に固定されています。
- 過去のブロックが1つの場合、難易度はその過去ブロックと同じになります。
- 過去のブロックが`n`個ない場合は、あるだけ用いられると思われます。


# ヒットとターゲット

NEM1のホワイトペーパーから類推すると、ヒットとターゲットという値がそれぞれ計算できます。ヒットはブロックの情報から計算され、ターゲットはアカウントのインポータンスと時刻から計算されます。とあるアカウントがヒット＜ターゲットを満たすとき、そのアカウントは新しいブロック生成の権利が発生します。

## ヒット

ブロック毎にヒットという値が計算されます。計算を高速化するために、NEM1から少し変わっています。


https://github.com/nemtech/catapult-server/blob/v0.6.0.1/src/catapult/chain/BlockScorer.cpp#L73

https://github.com/nemtech/catapult-server/blob/v0.6.0.1/src/catapult/utils/IntegerMath.cpp

```math
\begin{align}
\textrm{hit} = 2^{54} |\log_2{\frac{h}{2^{256}}}|
\end{align}
```

```math
h = \textrm{generation hash}
```

## ターゲット

あっているのかわかりません。

`timeDiff`が最新のブロックが生成されてからの経過秒数で、`importance`がアカウントのインポータンスです。

https://github.com/nemtech/catapult-server/blob/v0.6.0.1/src/catapult/chain/BlockScorer.cpp#L123

```math
b = \frac{899,999,998 * \textrm{importance}}{c} \\
t = \textrm{min}(e^{\frac{s}{1000}*\frac{\textrm{timeDiff} - g}{g}}, 100) \\
d = \textrm{difficulty for new block} \\
\textrm{target} = 2^{54}\frac{b}{d} t
```

```math
c = \textrm{totalChainImportance} = 15,000,000 \\
s = \textrm{blockTimeSmoothingFactor} = 3,000 \\
g = \textrm{blockGenerationTargetTime} = 15
```

# インポータンス

さすがにかなり自信ないです。

インポータンスは、`Stake Importance`と`Activity Importance`にわかれます。前者は残高に関係し、後者は手数料とかハーベストとかに関係します。`Activity Importance`は、FeeとBeneficialyにわかれます。

インポータンスは、毎ブロック計算されるわけではなく、一定ブロック数毎に計算されます。これをインターバルと言ったり計算期間と言ったり。この期間は`config-network.properties`の`importanceGrouping`で定義されます。

今回参照したソースはこちらです。

https://github.com/nemtech/catapult-server/blob/v0.6.0.1/plugins/coresystem/src/importance/CalculatorUtils.cpp#L116

https://github.com/nemtech/catapult-server/blob/v0.6.0.1/plugins/coresystem/src/importance/PosImportanceCalculator.cpp#L41


## Stake Importance

`ActiveHarvestingMosaics`は、推測ですが、ハーベスティングに参加しているアカウントの残高の合計（期間中にハーベストしたアカウントの残高）、もしくはハーベスティング参加条件を満たしているアカウントの残高の合計。`balance`はアカウントの残高。

```math
\textrm{stakeImportance} = T * \frac{\textrm{balance}}{\textrm{ActiveHarvestingMosaics}} * \frac{(100 - P)}{100}
```

```math
T = \textrm{totalChainImportance} = 15,000,000 \\
P = \textrm{importanceActivityPercentage} = 5
```

## Activity Importance

```math
\textrm{ActivityImportance} = \textrm{feeImportance} + \textrm{beneficiaryCountImportance}
```

### Fee Importance 

`TotalFeesPaid`はネットワーク全体で、`AccountTotalFeesPaid`はアカウントで、それぞれ計算期間中に支払った手数料の合計だと思います。

```math
\textrm{feeImportance} = T * P * \frac{M}{\textrm{balance}} * 0.8 * \frac{\textrm{feeRatio}}{100} \\
\textrm{feeRatio} = \frac{\textrm{AccountTotalFeesPaid}}{\textrm{TotalFeesPaid}}
```

```math
T = \textrm{totalChainImportance} = 15,000,000 \\
P = \textrm{importanceActivityPercentage} = 5 \\
M = \textrm{minHarvesterBalance} = 500
```

### Beneficiary Count Importance

```math
\textrm{beneficiaryCountImportance} = T * P * \frac{M}{\textrm{balance}} * 0.2 * \frac{\textrm{feeRatio}}{100} \\
\textrm{beneficiaryCountRatio} = \frac{\textrm{AccountBeneficiaryCount}}{\textrm{TotalBeneficiaryCount}}
```

```math
T = \textrm{totalChainImportance} = 15,000,000 \\
P = \textrm{importanceActivityPercentage} = 5 \\
M = \textrm{minHarvesterBalance} = 500
```

## Final Importance


$\textrm{totalActivityImportance} = 0$ のとき

```math
\textrm{Importance} = \textrm{stakeImportance} * \frac{100}{100 - P}
```

$\textrm{totalActivityImportance} \neq 0$ のとき

```math
\textrm{Importance} = \textrm{StakeImportance} +
\frac{\textrm{ActivityImportance}}{\textrm{totalActivityImportance}} * \frac{T * P}{100}
```

```math
T = \textrm{totalChainImportance} = 15,000,000 \\
P = \textrm{importanceActivityPercentage} = 5
```

# チェーンスコア

```math
\textrm{block score}_n = \textrm{difficulty}_n + \textrm{time elapsed since last block}
```

```math
\textrm{chain score} = \sum_n{\textrm{block score}_n}
```

## 参考記事

あとでこちらの記事と見比べてみたいと思います。

https://nemtech.github.io/concepts/consensus-algorithm.html

https://nemlog.nem.social/blog/25617