aff4b6d2c5
c2f61be Add a ForceSetArg method for testing (Matt Corallo) 4e04814 Lock mapArgs/mapMultiArgs access in util (Matt Corallo) 4cd373a Un-expose mapArgs from utils.h (Matt Corallo) 71fde55 Get rid of mapArgs direct access in ZMQ construction (Matt Corallo) 0cf86a6 Introduce (and use) an IsArgSet accessor method (Matt Corallo) 2b5f085 Fix non-const mapMultiArgs[] access after init. (Matt Corallo) c8042a4 Remove arguments to ParseConfigFile (Matt Corallo)
213 lines
6.8 KiB
C++
213 lines
6.8 KiB
C++
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
|
// Copyright (c) 2014-2017 The Dash Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#if defined(HAVE_CONFIG_H)
|
|
#include "config/dash-config.h"
|
|
#endif
|
|
|
|
#include "chainparams.h"
|
|
#include "clientversion.h"
|
|
#include "compat.h"
|
|
#include "rpc/server.h"
|
|
#include "init.h"
|
|
#include "noui.h"
|
|
#include "scheduler.h"
|
|
#include "util.h"
|
|
#include "masternodeconfig.h"
|
|
#include "httpserver.h"
|
|
#include "httprpc.h"
|
|
#include "utilstrencodings.h"
|
|
|
|
#include <boost/algorithm/string/predicate.hpp>
|
|
#include <boost/filesystem.hpp>
|
|
#include <boost/thread.hpp>
|
|
|
|
#include <stdio.h>
|
|
|
|
/* Introduction text for doxygen: */
|
|
|
|
/*! \mainpage Developer documentation
|
|
*
|
|
* \section intro_sec Introduction
|
|
*
|
|
* This is the developer documentation of the reference client for an experimental new digital currency called Dash (https://www.dash.org/),
|
|
* which enables instant payments to anyone, anywhere in the world. Dash uses peer-to-peer technology to operate
|
|
* with no central authority: managing transactions and issuing money are carried out collectively by the network.
|
|
*
|
|
* The software is a community-driven open source project, released under the MIT license.
|
|
*
|
|
* \section Navigation
|
|
* Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code.
|
|
*/
|
|
|
|
void WaitForShutdown(boost::thread_group* threadGroup)
|
|
{
|
|
bool fShutdown = ShutdownRequested();
|
|
// Tell the main threads to shutdown.
|
|
while (!fShutdown)
|
|
{
|
|
MilliSleep(200);
|
|
fShutdown = ShutdownRequested();
|
|
}
|
|
if (threadGroup)
|
|
{
|
|
Interrupt(*threadGroup);
|
|
threadGroup->join_all();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Start
|
|
//
|
|
bool AppInit(int argc, char* argv[])
|
|
{
|
|
boost::thread_group threadGroup;
|
|
CScheduler scheduler;
|
|
|
|
bool fRet = false;
|
|
|
|
//
|
|
// Parameters
|
|
//
|
|
// If Qt is used, parameters/dash.conf are parsed in qt/dash.cpp's main()
|
|
ParseParameters(argc, argv);
|
|
|
|
// Process help and version before taking care about datadir
|
|
if (IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version"))
|
|
{
|
|
std::string strUsage = strprintf(_("%s Daemon"), _(PACKAGE_NAME)) + " " + _("version") + " " + FormatFullVersion() + "\n";
|
|
|
|
if (IsArgSet("-version"))
|
|
{
|
|
strUsage += FormatParagraph(LicenseInfo());
|
|
}
|
|
else
|
|
{
|
|
strUsage += "\n" + _("Usage:") + "\n" +
|
|
" dashd [options] " + strprintf(_("Start %s Daemon"), _(PACKAGE_NAME)) + "\n";
|
|
|
|
strUsage += "\n" + HelpMessage(HMM_BITCOIND);
|
|
}
|
|
|
|
fprintf(stdout, "%s", strUsage.c_str());
|
|
return true;
|
|
}
|
|
|
|
try
|
|
{
|
|
bool datadirFromCmdLine = IsArgSet("-datadir");
|
|
if (datadirFromCmdLine && !boost::filesystem::is_directory(GetDataDir(false)))
|
|
{
|
|
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", GetArg("-datadir", "").c_str());
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME));
|
|
} catch (const std::exception& e) {
|
|
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
|
|
return false;
|
|
}
|
|
if (!datadirFromCmdLine && !boost::filesystem::is_directory(GetDataDir(false)))
|
|
{
|
|
fprintf(stderr, "Error: Specified data directory \"%s\" from config file does not exist.\n", GetArg("-datadir", "").c_str());
|
|
return EXIT_FAILURE;
|
|
}
|
|
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
|
|
try {
|
|
SelectParams(ChainNameFromCommandLine());
|
|
} catch (const std::exception& e) {
|
|
fprintf(stderr, "Error: %s\n", e.what());
|
|
return false;
|
|
}
|
|
|
|
// parse masternode.conf
|
|
std::string strErr;
|
|
if(!masternodeConfig.read(strErr)) {
|
|
fprintf(stderr,"Error reading masternode configuration file: %s\n", strErr.c_str());
|
|
return false;
|
|
}
|
|
|
|
// Command-line RPC
|
|
bool fCommandLine = false;
|
|
for (int i = 1; i < argc; i++)
|
|
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "dash:"))
|
|
fCommandLine = true;
|
|
|
|
if (fCommandLine)
|
|
{
|
|
fprintf(stderr, "Error: There is no RPC client functionality in dashd anymore. Use the dash-cli utility instead.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
// -server defaults to true for bitcoind but not for the GUI so do this here
|
|
SoftSetBoolArg("-server", true);
|
|
// Set this early so that parameter interactions go to console
|
|
InitLogging();
|
|
InitParameterInteraction();
|
|
if (!AppInitBasicSetup())
|
|
{
|
|
// InitError will have been called with detailed error, which ends up on console
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if (!AppInitParameterInteraction())
|
|
{
|
|
// InitError will have been called with detailed error, which ends up on console
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if (!AppInitSanityChecks())
|
|
{
|
|
// InitError will have been called with detailed error, which ends up on console
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if (GetBoolArg("-daemon", false))
|
|
{
|
|
#if HAVE_DECL_DAEMON
|
|
fprintf(stdout, "Dash Core server starting\n");
|
|
|
|
// Daemonize
|
|
if (daemon(1, 0)) { // don't chdir (1), do close FDs (0)
|
|
fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno));
|
|
return false;
|
|
}
|
|
#else
|
|
fprintf(stderr, "Error: -daemon is not supported on this operating system\n");
|
|
return false;
|
|
#endif // HAVE_DECL_DAEMON
|
|
}
|
|
|
|
fRet = AppInitMain(threadGroup, scheduler);
|
|
}
|
|
catch (const std::exception& e) {
|
|
PrintExceptionContinue(&e, "AppInit()");
|
|
} catch (...) {
|
|
PrintExceptionContinue(NULL, "AppInit()");
|
|
}
|
|
|
|
if (!fRet)
|
|
{
|
|
Interrupt(threadGroup);
|
|
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
|
|
// the startup-failure cases to make sure they don't result in a hang due to some
|
|
// thread-blocking-waiting-for-another-thread-during-startup case
|
|
} else {
|
|
WaitForShutdown(&threadGroup);
|
|
}
|
|
Shutdown();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
SetupEnvironment();
|
|
|
|
// Connect dashd signal handlers
|
|
noui_connect();
|
|
|
|
return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
}
|