Bitcoin Coreを読む 〜 generateコマンド
目的
generateおよびgeneratetoaddressコマンドの仕組みとブロック生成されるまでの流れをまとめる。
generateコマンドの処理
generateはrpcwallet.cppの中に定義されている。
generateはwalletからcoin base addressを取得する処理が入っているのでwalletの内部変数触りたかったから??
generateはcoinbase_script作成のためにwallet.cpp: void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)を呼び出している。
walletのkeyPoolから鍵を取り出して、P2PK scriptを生成して返している。walletのkeyPoolが空の場合はエラーになる?
最終的にはどちらもminig.cpp: UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, bool keepScript)を呼び出している。
bool keepScriptがtrueの時は、wallet.cpp: void CReserveKey::KeepKey()を呼び出しているのだけど、内部ではvchPubKey = CPubKey();してるので、pubkeyをクリアしてるようにしか見えない。。。。謎
generateから呼び出された場合は、coinbaseScriptの型がCReserveKeyになっており、KeepScript()がwallet.h: void KeepScript() override { KeepKey(); }でオーバーライドされている。
generatetoaddressコマンドの処理
generatetoaddressはmining.cppの中に定義されている。
generatetoaddressはcoinbase_script作成のためにstandard.cpp: CScript GetScriptForDestination(const CTxDestination& dest)を呼び出している。
CTxDestinationはboost::variant型。共用体。
GetScriptForDestination(const CTxDestination& dest)では、CTxDestinationの実際の型に応じて返すscriptを切り替えている。つまり渡されたaddress typeがP2PKHなのかP2WPKHなのか、P2SHなのかとかでinput scriptが変わってくるのでそれを切り替えている。
CTxDestinationの実際の型はkey_io.cpp: CTxDestination DecodeDestination(const std::string& str, const CChainParams& params)で選別している。
最終的にはどちらもminig.cpp: UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, bool keepScript)を呼び出している。
generateBlocksではnGenerate個数分のブロック作る処理を行なっている。1個のblock生成の処理はminer.cpp: std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx)で行なっている。