Bitcoind Chainparams調査
Bitcoin coreのchainparams.h/.cppを読んでパラメータの意味を調査する。なお本調査では、すべでのコードを精読したわけではなく、呼び出し部分などを参照しながら変数名から推測して執筆しているために、大いに間違っている可能性がある。間違いに気づいたら指摘していただけるとすごく嬉しい。
読んでいるコードは以下
大枠の理解
- main/test各ネットワークによってそれぞれ
chainparams.cppでデフォルト値を設定 chainparams.hでconsensus/params.hを呼んで内包している
consensus/params.hの中身
- この中の
struct Paramsをchainparamsから呼んでいる - 主に各BIPをアクティベートするためのパラメータと、PoWの設定に関するパラメータ
- BIP関連大枠としてはソフトフォークの方法として以下の3つがあり、それぞれのアクティベートのためのパラメータが設定されている
- 各ソフトフォークの方法に関してはこの記事がわかりやすい
- flag day activation: BIP16
- IsSuperMajority:BIP34、BIP65、BIP66
- version bits(BIP9):BIP112、BIP141
- BIP9に関するパラメータは
consensus/params.h中のstruct BIP9Deploymentで定義されている
- BIP9に関するパラメータは
パラメータ
| params | 型 | 説明 |
|---|---|---|
| nSubsidyHalvingInterval | int | ブロック毎の報酬を半減させるブロック数 |
| BIP16Exception | uint256 | BIP16が強制的にアクティブになるフラグのブロックハッシュ |
| BIP34Height | int | BIP34がアクティブになるブロック高 |
| BIP34Hash | uint256 | BIP34がアクティブになるブロックハッシュ |
| BIP65Height | int | BIP65がアクティブになったブロック高 |
| BIP66Height | int | BIP66がアクティブになったブロック高 |
| nRuleChangeActivationThreshold | unit32_t | ソフトフォーク時のアクティベーションするブロックの割合閾値(nMinerConfirmationWindowブロック中の何ブロックの形で指定) |
| nMinerConfirmationWindow | unit32_t | アクティベーション時の閾値を定義するためのブロック数(原則としてnPowTargetTimespan / nPowTargetSpacing?) |
| vDeployments[MAX_VERSION_BITS_DEPLOYMENTS] | BIP9Deployment | BIP9を利用したソフトフォークパラメータ(struct BIP9Deploymentで定義) |
| powLimit | unit256 | PoWのDifficulty最大値 |
| fPowAllowMinDifficultyBlocks | bool | PoWのDifficultyを最大値と同値を許すかどうか |
| fPowNoRetargeting | bool | PoWの難易度調整を行うかどうか |
| nPowTargetSpacing | int64_t | PoWの平均成功間隔(秒単位) |
| nPowTargetTimespan | int64_t | PoWの難易度調整を行う間隔(秒単位) |
| DifficultyAdjustmentInterval | int64_t | PoWの難易度調整を行う間隔(ブロック単位、nPowTargetTimespan / nPowTargetSpacingから計算して自動設定) |
| nMinimumChainWork | uint256 | 新規forkチェーン発見時に、最低限満たしているべきPoW難易度 |
| defaultAssumeValid | unit256 | 指定ブロック以前のブロックは正しいとみなすフラグとなるブロックのハッシュ |
chainparams.hの中身
- 中身をみていくと、「チェーンのパラメータ」というより、ノード同士のコミュニケーションであったり、ノード動作/ブートストラップのためのパラメータが主に設定されていた
| params | 型 | 説明 |
|---|---|---|
| consensus | Consensus::Params | 上記参照 |
| pchMessageStart | CMessageHeader::MessageStartChars | 通信時のメッセージヘッダーへ挿入するメッセージPrefix |
| nDefaultPort | int | ノードのデフォルト通信ポート |
| nPruneAfterHeight | uint64_t | 保存するブロックファイルを圧縮する時の、圧縮せず元データを維持する先頭ブロックからのブロック数 |
| m_assumed_blockchain_size | uint64_t | 現在の大まかなブロックチェーンデータサイズ(GB単位) |
| m_assumed_chain_state_size | uint64_t | 現在のChainStateDBの大まかなサイズ(GB単位) |
| vSeeds | std::vector\<std::string> | Seedノードのドメインリスト |
| base58Prefixes[MAX_BASE58_TYPES] | std::vector |
Base58Checkのencodingを行う際のプレフィックス(それぞれタイプはchainparams.hのclass CChainParams内enum Base58Typeで定義) |
| bech32_hrp | std::string | bech32におけるHuman Readable Part |
| strNetworkID | std::string | ネットワークを識別するID(mainnet/testnetなど) |
| genesis | CBlock | Gensisブロック(chainparams.cpp内のCreateGenesisBlock()を用いて生成) |
| vFixedSeeds | std::vector |
SeedノードのIPv6アドレス(chainparamsseeds.h内で定義) |
| fDefaultConsistencyChecks | bool | ノード起動時にBlockIndexやmempoolなどに一貫性があるかのチェックを実施するか(要調査) |
| fRequireStandard | bool | スタンダードなTXフォーマットでないTXを扱うかどうか(testnetではtrue) |
| checkpointData | CCheckpointData | 検証時にチェックポイントとするブロック高とブロックハッシュのリスト(構造はcheckpoint.hで定義) |
| chainTxData | ChainTxData | チェーンの中にあるTXの統計データなど、ノードブートストラップ時のチェーン検証進捗計算のために使われている?(詳細はchainparams.h内のstruct ChainTxDataで定義) |
| m_fallback_fee_enabled | bool | WalletでTX作成時にfeeが指定されなかった時に、指定値のfeeを払うようにするかどうか(feeの指定値は起動時に-fallbackfeeパラメータで指定) |
感想
consensus/params.hの中でソフトフォーク関連のパラメータを定義しているのはなんとなく面白い- しかし、ハードコードしている部分が増えるのはノードをブートストラップする時の効率がよくなるのは理解できるが、ソフトウェアとガバナンスの観点からは疑問
consensus/params.hの中に半減期の期間の定義があるのはそこで本当にいいのだろうか?と直感的には思ったnMinerConfirmationWindowがDifficultyAdjustmentIntervalとは別に設定されているのは面白いかもしれない- 様々なパラメータが歴史的経緯とともに混沌としていった形跡が見受けられ、一度再設計してみるのも面白いかもしれない
- BIP関連
ノードの運用用のパラメータ(
fDefaultConsistencyChecksなど)とノードがコミュニケーションを取るためのパラメータはうまく整理して分離できたりしないだろうか- Bitcoinノードの実装と運用、そしてガバナンスに関してコードの観点から疑問を再確認できたので、いい機会だった
最初に読み始めたコードがv0.17ベースのものだったので、すでに削除されたパラメータ(
fMineBlocksOnDemand)についても調査していた- この辺の歴史的経緯を整理しながらパラメータを整理してドキュメンテーションするのもこのコミュニティには必要なんじゃないだろうかと思ったり