Files
thehub/hub/bitcoind.cpp
T
TomZ 175096b2bd Refactor: move files
Move some files back to the server "library".
Merge the 'console' lib with server, as it doesn't really make sense with
just one file and nobody exclusively linking to it.

The server "libary" is not really a library, its the place we put all
the files shared by hub-qt hub-cli and hub.
We no longer depend on these files from other places (mostly due to
moving to the new logging framework) and as such we can move the files
back.
2019-11-13 19:09:24 +01:00

221 lines
6.8 KiB
C++

/*
* This file is part of the Flowee project
* Copyright (c) 2009-2010 Satoshi Nakamoto
* Copyright (c) 2009-2015 The Bitcoin Core developers
* Copyright (C) 2018-2019 Tom Zander <tomz@freedommail.ch>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "chainparams.h"
#include "clientversion.h"
#include "rpcserver.h"
#include <init.h>
#include <server/main.h>
#include "noui.h"
#include "scheduler.h"
#include <serverutil.h>
#include "httpserver.h"
#include "httprpc.h"
#include "rpcserver.h"
#include "Application.h"
#include "APIServer.h"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <AddressMonitorService.h>
#include <BlockNotificationService.h>
#include <cstdio>
static bool fDaemon;
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();
}
}
static bool SelectChain()
{
try {
SelectParams(ChainNameFromCommandLine());
return true;
} catch (const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
return false;
}
}
//////////////////////////////////////////////////////////////////////////////
//
// Start
//
bool AppInit(int argc, char* argv[])
{
boost::thread_group threadGroup;
CScheduler scheduler;
bool fRet = false;
//
// Parameters
//
// If Qt is used, parameters/flowee.conf are parsed in qt/bitcoin.cpp's main()
Settings::Hub allowedArgs;
try {
ParseParameters(argc, argv, allowedArgs);
} catch (const std::exception& e) {
fprintf(stderr, "Error parsing program options: %s\n", e.what());
return false;
}
// Process help and version before taking care about datadir
if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version"))
{
std::string strUsage = _("Flowee the Hub") + " " + _("version") + " " + FormatFullVersion() + "\n";
if (!mapArgs.count("-version")) {
strUsage += "\n" + _("Usage:") + "\n" +
" hub [options] " + _("Start Flowee the Hub") + "\n";
strUsage += "\n" + allowedArgs.helpMessage();
}
fprintf(stdout, "%s", strUsage.c_str());
return false;
}
std::unique_ptr<Api::Server> apiServer;
std::unique_ptr<AddressMonitorService> addressMonitorService;
std::unique_ptr<BlockNotificationService> blockNotificationService;
try
{
for (int i = 1; i < argc; i++) {
if (!IsSwitchChar(argv[i][0])) {
fprintf(stderr, "Error: unexpected argument found. Options go in the form of -name=value\n");
exit(1);
break;
}
}
std::string dd = GetArg("-datadir", "");
if (!dd.empty()) {
auto path = boost::filesystem::system_complete(dd);
if (!boost::filesystem::is_directory(path)) {
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", dd.c_str());
return false;
}
}
boost::filesystem::path pathConfigFile = GetArg("-conf", "");
const bool confPathSet = pathConfigFile.is_complete();
if (!confPathSet) // first select chain, so we read the right conf file.
if (!SelectChain()) return false;
try {
ReadConfigFile(mapArgs, mapMultiArgs);
} catch (const std::exception& e) {
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
return false;
}
if (confPathSet) // after raeding the user-indicated conf file, select chain (including conf file opts)
if (!SelectChain()) return false;
#ifndef WIN32
fDaemon = GetBoolArg("-daemon", false);
if (fDaemon)
{
fprintf(stdout, "Flowee Hub server starting\n");
// Daemonize
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
return false;
}
if (pid > 0) // Parent process, pid is child process id
{
return true;
}
// Child process falls through to rest of initialization
pid_t sid = setsid();
if (sid < 0)
fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
}
#endif
SoftSetBoolArg("-server", true);
// Set this early so that parameter interactions go to console
InitLogging();
InitParameterInteraction();
fRet = AppInit2(threadGroup, scheduler);
if (fRet) {
if (GetBoolArg("-api", true)) {
apiServer.reset(new Api::Server(Application::instance()->ioService()));
addressMonitorService.reset(new AddressMonitorService());
blockNotificationService.reset(new BlockNotificationService());
extern CTxMemPool mempool;
addressMonitorService->setMempool(&mempool);
apiServer->addService(addressMonitorService.get());
apiServer->addService(blockNotificationService.get());
}
}
}
catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInit()");
} catch (...) {
PrintExceptionContinue(nullptr, "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);
}
addressMonitorService.reset();
apiServer.reset();
Shutdown();
return fRet;
}
int main(int argc, char* argv[])
{
SetupEnvironment();
// Connect hub signal handlers
noui_connect();
return (AppInit(argc, argv) ? 0 : 1);
}