Changeset View
Changeset View
Standalone View
Standalone View
src/init.cpp
Show All 17 Lines | |||||
#include <compat/sanity.h> | #include <compat/sanity.h> | ||||
#include <config.h> | #include <config.h> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <flatfile.h> | #include <flatfile.h> | ||||
#include <fs.h> | #include <fs.h> | ||||
#include <httprpc.h> | #include <httprpc.h> | ||||
#include <httpserver.h> | #include <httpserver.h> | ||||
#include <index/txindex.h> | #include <index/txindex.h> | ||||
#include <interfaces/chain.h> | |||||
#include <key.h> | #include <key.h> | ||||
#include <miner.h> | #include <miner.h> | ||||
#include <net.h> | #include <net.h> | ||||
#include <net_processing.h> | #include <net_processing.h> | ||||
#include <netbase.h> | #include <netbase.h> | ||||
#include <policy/policy.h> | #include <policy/policy.h> | ||||
#include <rpc/blockchain.h> | #include <rpc/blockchain.h> | ||||
#include <rpc/register.h> | #include <rpc/register.h> | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | void Shutdown(InitInterfaces &interfaces) { | ||||
/// only does this if the respective module was initialized. | /// only does this if the respective module was initialized. | ||||
RenameThread("bitcoin-shutoff"); | RenameThread("bitcoin-shutoff"); | ||||
g_mempool.AddTransactionsUpdated(1); | g_mempool.AddTransactionsUpdated(1); | ||||
StopHTTPRPC(); | StopHTTPRPC(); | ||||
StopREST(); | StopREST(); | ||||
StopRPC(); | StopRPC(); | ||||
StopHTTPServer(); | StopHTTPServer(); | ||||
g_wallet_init_interface.Flush(); | for (const auto &client : interfaces.chain_clients) { | ||||
client->flush(); | |||||
} | |||||
StopMapPort(); | StopMapPort(); | ||||
// Because these depend on each-other, we make sure that neither can be | // Because these depend on each-other, we make sure that neither can be | ||||
// using the other before destroying them. | // using the other before destroying them. | ||||
if (peerLogic) { | if (peerLogic) { | ||||
UnregisterValidationInterface(peerLogic.get()); | UnregisterValidationInterface(peerLogic.get()); | ||||
} | } | ||||
if (g_connman) { | if (g_connman) { | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | // cases and make next startup faster by avoiding rescan. | ||||
if (pcoinsTip != nullptr) { | if (pcoinsTip != nullptr) { | ||||
FlushStateToDisk(); | FlushStateToDisk(); | ||||
} | } | ||||
pcoinsTip.reset(); | pcoinsTip.reset(); | ||||
pcoinscatcher.reset(); | pcoinscatcher.reset(); | ||||
pcoinsdbview.reset(); | pcoinsdbview.reset(); | ||||
pblocktree.reset(); | pblocktree.reset(); | ||||
} | } | ||||
g_wallet_init_interface.Stop(); | for (const auto &client : interfaces.chain_clients) { | ||||
client->stop(); | |||||
} | |||||
#if ENABLE_ZMQ | #if ENABLE_ZMQ | ||||
if (g_zmq_notification_interface) { | if (g_zmq_notification_interface) { | ||||
UnregisterValidationInterface(g_zmq_notification_interface); | UnregisterValidationInterface(g_zmq_notification_interface); | ||||
delete g_zmq_notification_interface; | delete g_zmq_notification_interface; | ||||
g_zmq_notification_interface = nullptr; | g_zmq_notification_interface = nullptr; | ||||
} | } | ||||
#endif | #endif | ||||
#ifndef WIN32 | #ifndef WIN32 | ||||
try { | try { | ||||
fs::remove(GetPidFile()); | fs::remove(GetPidFile()); | ||||
} catch (const fs::filesystem_error &e) { | } catch (const fs::filesystem_error &e) { | ||||
LogPrintf("%s: Unable to remove pidfile: %s\n", __func__, e.what()); | LogPrintf("%s: Unable to remove pidfile: %s\n", __func__, e.what()); | ||||
} | } | ||||
#endif | #endif | ||||
UnregisterAllValidationInterfaces(); | UnregisterAllValidationInterfaces(); | ||||
GetMainSignals().UnregisterBackgroundSignalScheduler(); | GetMainSignals().UnregisterBackgroundSignalScheduler(); | ||||
GetMainSignals().UnregisterWithMempoolSignals(g_mempool); | GetMainSignals().UnregisterWithMempoolSignals(g_mempool); | ||||
g_wallet_init_interface.Close(); | interfaces.chain_clients.clear(); | ||||
globalVerifyHandle.reset(); | globalVerifyHandle.reset(); | ||||
ECC_Stop(); | ECC_Stop(); | ||||
LogPrintf("%s: done\n", __func__); | LogPrintf("%s: done\n", __func__); | ||||
} | } | ||||
/** | /** | ||||
* Signal handlers are very limited in what they are allowed to do. | * Signal handlers are very limited in what they are allowed to do. | ||||
* The execution context the handler is invoked in is not guaranteed, | * The execution context the handler is invoked in is not guaranteed, | ||||
▲ Show 20 Lines • Show All 1,613 Lines • ▼ Show 20 Lines | #endif | ||||
CScheduler::Function serviceLoop = | CScheduler::Function serviceLoop = | ||||
std::bind(&CScheduler::serviceQueue, &scheduler); | std::bind(&CScheduler::serviceQueue, &scheduler); | ||||
threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>, | threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>, | ||||
"scheduler", serviceLoop)); | "scheduler", serviceLoop)); | ||||
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); | GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); | ||||
GetMainSignals().RegisterWithMempoolSignals(g_mempool); | GetMainSignals().RegisterWithMempoolSignals(g_mempool); | ||||
// Create client interfaces for wallets that are supposed to be loaded | |||||
// according to -wallet and -disablewallet options. This only constructs | |||||
// the interfaces, it doesn't load wallet data. Wallets actually get loaded | |||||
// when load() and start() interface methods are called below. | |||||
g_wallet_init_interface.Construct(interfaces); | |||||
/** | /** | ||||
* Register RPC commands regardless of -server setting so they will be | * Register RPC commands regardless of -server setting so they will be | ||||
* available in the GUI RPC console even if external calls are disabled. | * available in the GUI RPC console even if external calls are disabled. | ||||
*/ | */ | ||||
RegisterAllRPCCommands(config, rpcServer, tableRPC); | RegisterAllRPCCommands(config, rpcServer, tableRPC); | ||||
g_wallet_init_interface.RegisterRPC(tableRPC); | for (const auto &client : interfaces.chain_clients) { | ||||
client->registerRpcs(); | |||||
} | |||||
g_rpc_interfaces = &interfaces; | g_rpc_interfaces = &interfaces; | ||||
#if ENABLE_ZMQ | #if ENABLE_ZMQ | ||||
RegisterZMQRPCCommands(tableRPC); | RegisterZMQRPCCommands(tableRPC); | ||||
#endif | #endif | ||||
/** | /** | ||||
* Start the RPC server. It will be started in "warmup" mode and not | * Start the RPC server. It will be started in "warmup" mode and not | ||||
* process calls yet (but it will verify that the server is there and will | * process calls yet (but it will verify that the server is there and will | ||||
* be ready later). Warmup mode will be completed when initialisation is | * be ready later). Warmup mode will be completed when initialisation is | ||||
* finished. | * finished. | ||||
*/ | */ | ||||
if (gArgs.GetBoolArg("-server", false)) { | if (gArgs.GetBoolArg("-server", false)) { | ||||
uiInterface.InitMessage_connect(SetRPCWarmupStatus); | uiInterface.InitMessage_connect(SetRPCWarmupStatus); | ||||
if (!AppInitServers(config, httpRPCRequestProcessor)) { | if (!AppInitServers(config, httpRPCRequestProcessor)) { | ||||
return InitError( | return InitError( | ||||
_("Unable to start HTTP server. See debug log for details.")); | _("Unable to start HTTP server. See debug log for details.")); | ||||
} | } | ||||
} | } | ||||
// Step 5: verify wallet database integrity | // Step 5: verify wallet database integrity | ||||
if (!g_wallet_init_interface.Verify(chainparams, *interfaces.chain)) { | for (const auto &client : interfaces.chain_clients) { | ||||
if (!client->verify(chainparams)) { | |||||
return false; | return false; | ||||
} | } | ||||
} | |||||
// Step 6: network initialization | // Step 6: network initialization | ||||
// Note that we absolutely cannot open any actual connections | // Note that we absolutely cannot open any actual connections | ||||
// until the very end ("start node") as the UTXO/block state | // until the very end ("start node") as the UTXO/block state | ||||
// is not yet setup and may end up being set up twice if we | // is not yet setup and may end up being set up twice if we | ||||
// need to reindex later. | // need to reindex later. | ||||
▲ Show 20 Lines • Show All 375 Lines • ▼ Show 20 Lines | #endif | ||||
// Step 8: load indexers | // Step 8: load indexers | ||||
if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { | if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { | ||||
g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex); | g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex); | ||||
g_txindex->Start(); | g_txindex->Start(); | ||||
} | } | ||||
// Step 9: load wallet | // Step 9: load wallet | ||||
if (!g_wallet_init_interface.Open(chainparams, *interfaces.chain)) { | for (const auto &client : interfaces.chain_clients) { | ||||
if (!client->load(chainparams)) { | |||||
return false; | return false; | ||||
} | } | ||||
} | |||||
// Step 10: data directory maintenance | // Step 10: data directory maintenance | ||||
// if pruning, unset the service bit and perform the initial blockstore | // if pruning, unset the service bit and perform the initial blockstore | ||||
// prune after any wallet rescanning has taken place. | // prune after any wallet rescanning has taken place. | ||||
if (fPruneMode) { | if (fPruneMode) { | ||||
LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); | LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); | ||||
nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK); | nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK); | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | if (!g_connman->Start(scheduler, connOptions)) { | ||||
return false; | return false; | ||||
} | } | ||||
// Step 13: finished | // Step 13: finished | ||||
SetRPCWarmupFinished(); | SetRPCWarmupFinished(); | ||||
uiInterface.InitMessage(_("Done loading")); | uiInterface.InitMessage(_("Done loading")); | ||||
g_wallet_init_interface.Start(scheduler); | for (const auto &client : interfaces.chain_clients) { | ||||
client->start(scheduler); | |||||
} | |||||
scheduler.scheduleEvery( | scheduler.scheduleEvery( | ||||
[] { | [] { | ||||
g_banman->DumpBanlist(); | g_banman->DumpBanlist(); | ||||
return true; | return true; | ||||
}, | }, | ||||
DUMP_BANS_INTERVAL * 1000); | DUMP_BANS_INTERVAL * 1000); | ||||
return true; | return true; | ||||
} | } |