Changeset View
Changeset View
Standalone View
Standalone View
src/init.cpp
Show First 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | void Interrupt() { | ||||
if (g_connman) { | if (g_connman) { | ||||
g_connman->Interrupt(); | g_connman->Interrupt(); | ||||
} | } | ||||
if (g_txindex) { | if (g_txindex) { | ||||
g_txindex->Interrupt(); | g_txindex->Interrupt(); | ||||
} | } | ||||
} | } | ||||
void Shutdown(InitInterfaces &interfaces) { | void Shutdown(NodeContext &node) { | ||||
LogPrintf("%s: In progress...\n", __func__); | LogPrintf("%s: In progress...\n", __func__); | ||||
static RecursiveMutex cs_Shutdown; | static RecursiveMutex cs_Shutdown; | ||||
TRY_LOCK(cs_Shutdown, lockShutdown); | TRY_LOCK(cs_Shutdown, lockShutdown); | ||||
if (!lockShutdown) { | if (!lockShutdown) { | ||||
return; | return; | ||||
} | } | ||||
/// Note: Shutdown() must be able to handle cases in which initialization | /// Note: Shutdown() must be able to handle cases in which initialization | ||||
/// failed part of the way, for example if the data directory was found to | /// failed part of the way, for example if the data directory was found to | ||||
/// be locked. Be sure that anything that writes files or flushes caches | /// be locked. Be sure that anything that writes files or flushes caches | ||||
/// only does this if the respective module was initialized. | /// only does this if the respective module was initialized. | ||||
util::ThreadRename("shutoff"); | util::ThreadRename("shutoff"); | ||||
g_mempool.AddTransactionsUpdated(1); | g_mempool.AddTransactionsUpdated(1); | ||||
StopHTTPRPC(); | StopHTTPRPC(); | ||||
StopREST(); | StopREST(); | ||||
StopRPC(); | StopRPC(); | ||||
StopHTTPServer(); | StopHTTPServer(); | ||||
for (const auto &client : interfaces.chain_clients) { | for (const auto &client : node.chain_clients) { | ||||
client->flush(); | client->flush(); | ||||
} | } | ||||
StopMapPort(); | StopMapPort(); | ||||
// Because avalanche and the network depend on each other, it is important | // Because avalanche and the network depend on each other, it is important | ||||
// to shut them down in this order: | // to shut them down in this order: | ||||
// 1. Stop avalanche event loop. | // 1. Stop avalanche event loop. | ||||
// 2. Shutdown network processing. | // 2. Shutdown network processing. | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | // cases and make next startup faster by avoiding rescan. | ||||
if (pcoinsTip != nullptr) { | if (pcoinsTip != nullptr) { | ||||
::ChainstateActive().ForceFlushStateToDisk(); | ::ChainstateActive().ForceFlushStateToDisk(); | ||||
} | } | ||||
pcoinsTip.reset(); | pcoinsTip.reset(); | ||||
pcoinscatcher.reset(); | pcoinscatcher.reset(); | ||||
pcoinsdbview.reset(); | pcoinsdbview.reset(); | ||||
pblocktree.reset(); | pblocktree.reset(); | ||||
} | } | ||||
for (const auto &client : interfaces.chain_clients) { | for (const auto &client : node.chain_clients) { | ||||
client->stop(); | 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 | ||||
try { | try { | ||||
if (!fs::remove(GetPidFile())) { | if (!fs::remove(GetPidFile())) { | ||||
LogPrintf("%s: Unable to remove PID file: File does not exist\n", | LogPrintf("%s: Unable to remove PID file: File does not exist\n", | ||||
__func__); | __func__); | ||||
} | } | ||||
} catch (const fs::filesystem_error &e) { | } catch (const fs::filesystem_error &e) { | ||||
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, | LogPrintf("%s: Unable to remove PID file: %s\n", __func__, | ||||
fsbridge::get_filesystem_error_message(e)); | fsbridge::get_filesystem_error_message(e)); | ||||
} | } | ||||
interfaces.chain_clients.clear(); | node.chain_clients.clear(); | ||||
UnregisterAllValidationInterfaces(); | UnregisterAllValidationInterfaces(); | ||||
GetMainSignals().UnregisterBackgroundSignalScheduler(); | GetMainSignals().UnregisterBackgroundSignalScheduler(); | ||||
GetMainSignals().UnregisterWithMempoolSignals(g_mempool); | GetMainSignals().UnregisterWithMempoolSignals(g_mempool); | ||||
globalVerifyHandle.reset(); | globalVerifyHandle.reset(); | ||||
ECC_Stop(); | ECC_Stop(); | ||||
LogPrintf("%s: done\n", __func__); | LogPrintf("%s: done\n", __func__); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,641 Lines • ▼ Show 20 Lines | if (!LockDataDirectory(false)) { | ||||
// Detailed error printed inside LockDataDirectory | // Detailed error printed inside LockDataDirectory | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool AppInitMain(Config &config, RPCServer &rpcServer, | bool AppInitMain(Config &config, RPCServer &rpcServer, | ||||
HTTPRPCRequestProcessor &httpRPCRequestProcessor, | HTTPRPCRequestProcessor &httpRPCRequestProcessor, | ||||
InitInterfaces &interfaces) { | NodeContext &node) { | ||||
// Step 4a: application initialization | // Step 4a: application initialization | ||||
const CChainParams &chainparams = config.GetChainParams(); | const CChainParams &chainparams = config.GetChainParams(); | ||||
if (!CreatePidFile()) { | if (!CreatePidFile()) { | ||||
// Detailed error printed inside CreatePidFile(). | // Detailed error printed inside CreatePidFile(). | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | bool AppInitMain(Config &config, RPCServer &rpcServer, | ||||
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 | // Create client interfaces for wallets that are supposed to be loaded | ||||
// according to -wallet and -disablewallet options. This only constructs | // according to -wallet and -disablewallet options. This only constructs | ||||
// the interfaces, it doesn't load wallet data. Wallets actually get loaded | // the interfaces, it doesn't load wallet data. Wallets actually get loaded | ||||
// when load() and start() interface methods are called below. | // when load() and start() interface methods are called below. | ||||
g_wallet_init_interface.Construct(interfaces); | g_wallet_init_interface.Construct(node); | ||||
/** | /** | ||||
* 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); | ||||
for (const auto &client : interfaces.chain_clients) { | for (const auto &client : node.chain_clients) { | ||||
client->registerRpcs(); | client->registerRpcs(); | ||||
} | } | ||||
g_rpc_interfaces = &interfaces; | g_rpc_node = &node; | ||||
#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.") | ||||
.translated); | .translated); | ||||
} | } | ||||
} | } | ||||
// Step 5: verify wallet database integrity | // Step 5: verify wallet database integrity | ||||
for (const auto &client : interfaces.chain_clients) { | for (const auto &client : node.chain_clients) { | ||||
if (!client->verify(chainparams)) { | 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 | ||||
▲ Show 20 Lines • Show All 402 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 | ||||
for (const auto &client : interfaces.chain_clients) { | for (const auto &client : node.chain_clients) { | ||||
if (!client->load(chainparams)) { | 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 | ||||
▲ Show 20 Lines • Show All 140 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").translated); | uiInterface.InitMessage(_("Done loading").translated); | ||||
for (const auto &client : interfaces.chain_clients) { | for (const auto &client : node.chain_clients) { | ||||
client->start(scheduler); | 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); | ||||
// Start Avalanche's event loop. | // Start Avalanche's event loop. | ||||
g_avalanche->startEventLoop(scheduler); | g_avalanche->startEventLoop(scheduler); | ||||
return true; | return true; | ||||
} | } |