Remove direct bitcoin calls from qt/bitcoin.cpp
This commit is contained in:
parent
ea73b84d2d
commit
71e0d90876
6 changed files with 215 additions and 47 deletions
|
@ -104,6 +104,8 @@ BITCOIN_CORE_H = \
|
|||
httpserver.h \
|
||||
indirectmap.h \
|
||||
init.h \
|
||||
interface/handler.h \
|
||||
interface/node.h \
|
||||
key.h \
|
||||
key_io.h \
|
||||
keystore.h \
|
||||
|
@ -357,6 +359,8 @@ libbitcoin_util_a_SOURCES = \
|
|||
compat/glibcxx_sanity.cpp \
|
||||
compat/strnlen.cpp \
|
||||
fs.cpp \
|
||||
interface/handler.cpp \
|
||||
interface/node.cpp \
|
||||
random.cpp \
|
||||
rpc/protocol.cpp \
|
||||
rpc/util.cpp \
|
||||
|
|
33
src/interface/handler.cpp
Normal file
33
src/interface/handler.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <interface/handler.h>
|
||||
|
||||
#include <util.h>
|
||||
|
||||
#include <boost/signals2/connection.hpp>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace interface {
|
||||
namespace {
|
||||
|
||||
class HandlerImpl : public Handler
|
||||
{
|
||||
public:
|
||||
HandlerImpl(boost::signals2::connection connection) : m_connection(std::move(connection)) {}
|
||||
|
||||
void disconnect() override { m_connection.disconnect(); }
|
||||
|
||||
boost::signals2::scoped_connection m_connection;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection)
|
||||
{
|
||||
return MakeUnique<HandlerImpl>(std::move(connection));
|
||||
}
|
||||
|
||||
} // namespace interface
|
35
src/interface/handler.h
Normal file
35
src/interface/handler.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_INTERFACE_HANDLER_H
|
||||
#define BITCOIN_INTERFACE_HANDLER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace signals2 {
|
||||
class connection;
|
||||
} // namespace signals2
|
||||
} // namespace boost
|
||||
|
||||
namespace interface {
|
||||
|
||||
//! Generic interface for managing an event handler or callback function
|
||||
//! registered with another interface. Has a single disconnect method to cancel
|
||||
//! the registration and prevent any future notifications.
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
virtual ~Handler() {}
|
||||
|
||||
//! Disconnect the handler.
|
||||
virtual void disconnect() = 0;
|
||||
};
|
||||
|
||||
//! Return handler wrapping a boost signal connection.
|
||||
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection);
|
||||
|
||||
} // namespace interface
|
||||
|
||||
#endif // BITCOIN_INTERFACE_HANDLER_H
|
53
src/interface/node.cpp
Normal file
53
src/interface/node.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <interface/node.h>
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <init.h>
|
||||
#include <interface/handler.h>
|
||||
#include <scheduler.h>
|
||||
#include <ui_interface.h>
|
||||
#include <util.h>
|
||||
#include <warnings.h>
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace interface {
|
||||
namespace {
|
||||
|
||||
class NodeImpl : public Node
|
||||
{
|
||||
void parseParameters(int argc, const char* const argv[]) override
|
||||
{
|
||||
gArgs.ParseParameters(argc, argv);
|
||||
}
|
||||
void readConfigFile(const std::string& conf_path) override { gArgs.ReadConfigFile(conf_path); }
|
||||
void selectParams(const std::string& network) override { SelectParams(network); }
|
||||
void initLogging() override { InitLogging(); }
|
||||
void initParameterInteraction() override { InitParameterInteraction(); }
|
||||
std::string getWarnings(const std::string& type) override { return GetWarnings(type); }
|
||||
bool baseInitialize() override
|
||||
{
|
||||
return AppInitBasicSetup() && AppInitParameterInteraction() && AppInitSanityChecks() &&
|
||||
AppInitLockDataDirectory();
|
||||
}
|
||||
bool appInitMain() override { return AppInitMain(); }
|
||||
void appShutdown() override
|
||||
{
|
||||
Interrupt();
|
||||
Shutdown();
|
||||
}
|
||||
void startShutdown() override { StartShutdown(); }
|
||||
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
|
||||
{
|
||||
return MakeHandler(::uiInterface.InitMessage.connect(fn));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Node> MakeNode() { return MakeUnique<NodeImpl>(); }
|
||||
|
||||
} // namespace interface
|
62
src/interface/node.h
Normal file
62
src/interface/node.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_INTERFACE_NODE_H
|
||||
#define BITCOIN_INTERFACE_NODE_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace interface {
|
||||
|
||||
class Handler;
|
||||
|
||||
//! Top-level interface for a bitcoin node (bitcoind process).
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
virtual ~Node() {}
|
||||
|
||||
//! Set command line arguments.
|
||||
virtual void parseParameters(int argc, const char* const argv[]) = 0;
|
||||
|
||||
//! Load settings from configuration file.
|
||||
virtual void readConfigFile(const std::string& conf_path) = 0;
|
||||
|
||||
//! Choose network parameters.
|
||||
virtual void selectParams(const std::string& network) = 0;
|
||||
|
||||
//! Init logging.
|
||||
virtual void initLogging() = 0;
|
||||
|
||||
//! Init parameter interaction.
|
||||
virtual void initParameterInteraction() = 0;
|
||||
|
||||
//! Get warnings.
|
||||
virtual std::string getWarnings(const std::string& type) = 0;
|
||||
|
||||
//! Initialize app dependencies.
|
||||
virtual bool baseInitialize() = 0;
|
||||
|
||||
//! Start node.
|
||||
virtual bool appInitMain() = 0;
|
||||
|
||||
//! Stop node.
|
||||
virtual void appShutdown() = 0;
|
||||
|
||||
//! Start shutdown.
|
||||
virtual void startShutdown() = 0;
|
||||
|
||||
//! Register handler for init messages.
|
||||
using InitMessageFn = std::function<void(const std::string& message)>;
|
||||
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
|
||||
};
|
||||
|
||||
//! Return implementation of Node interface.
|
||||
std::unique_ptr<Node> MakeNode();
|
||||
|
||||
} // namespace interface
|
||||
|
||||
#endif // BITCOIN_INTERFACE_NODE_H
|
|
@ -27,6 +27,8 @@
|
|||
#endif
|
||||
|
||||
#include <init.h>
|
||||
#include <interface/handler.h>
|
||||
#include <interface/node.h>
|
||||
#include <rpc/server.h>
|
||||
#include <ui_interface.h>
|
||||
#include <uint256.h>
|
||||
|
@ -180,11 +182,7 @@ class BitcoinCore: public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BitcoinCore();
|
||||
/** Basic initialization, before starting initialization/shutdown thread.
|
||||
* Return true on success.
|
||||
*/
|
||||
static bool baseInitialize();
|
||||
explicit BitcoinCore(interface::Node& node);
|
||||
|
||||
public Q_SLOTS:
|
||||
void initialize();
|
||||
|
@ -196,9 +194,10 @@ Q_SIGNALS:
|
|||
void runawayException(const QString &message);
|
||||
|
||||
private:
|
||||
|
||||
/// Pass fatal exception message to UI thread
|
||||
void handleRunawayException(const std::exception *e);
|
||||
|
||||
interface::Node& m_node;
|
||||
};
|
||||
|
||||
/** Main Bitcoin application object */
|
||||
|
@ -206,7 +205,7 @@ class BitcoinApplication: public QApplication
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BitcoinApplication(int &argc, char **argv);
|
||||
explicit BitcoinApplication(interface::Node& node, int &argc, char **argv);
|
||||
~BitcoinApplication();
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
|
@ -247,6 +246,7 @@ Q_SIGNALS:
|
|||
|
||||
private:
|
||||
QThread *coreThread;
|
||||
interface::Node& m_node;
|
||||
OptionsModel *optionsModel;
|
||||
ClientModel *clientModel;
|
||||
BitcoinGUI *window;
|
||||
|
@ -264,36 +264,15 @@ private:
|
|||
|
||||
#include <qt/bitcoin.moc>
|
||||
|
||||
BitcoinCore::BitcoinCore():
|
||||
QObject()
|
||||
BitcoinCore::BitcoinCore(interface::Node& node) :
|
||||
QObject(), m_node(node)
|
||||
{
|
||||
}
|
||||
|
||||
void BitcoinCore::handleRunawayException(const std::exception *e)
|
||||
{
|
||||
PrintExceptionContinue(e, "Runaway exception");
|
||||
Q_EMIT runawayException(QString::fromStdString(GetWarnings("gui")));
|
||||
}
|
||||
|
||||
bool BitcoinCore::baseInitialize()
|
||||
{
|
||||
if (!AppInitBasicSetup())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!AppInitParameterInteraction())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!AppInitSanityChecks())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!AppInitLockDataDirectory())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings("gui")));
|
||||
}
|
||||
|
||||
void BitcoinCore::initialize()
|
||||
|
@ -301,7 +280,7 @@ void BitcoinCore::initialize()
|
|||
try
|
||||
{
|
||||
qDebug() << __func__ << ": Running initialization in thread";
|
||||
bool rv = AppInitMain();
|
||||
bool rv = m_node.appInitMain();
|
||||
Q_EMIT initializeResult(rv);
|
||||
} catch (const std::exception& e) {
|
||||
handleRunawayException(&e);
|
||||
|
@ -315,8 +294,7 @@ void BitcoinCore::shutdown()
|
|||
try
|
||||
{
|
||||
qDebug() << __func__ << ": Running Shutdown in thread";
|
||||
Interrupt();
|
||||
Shutdown();
|
||||
m_node.appShutdown();
|
||||
qDebug() << __func__ << ": Shutdown finished";
|
||||
Q_EMIT shutdownResult();
|
||||
} catch (const std::exception& e) {
|
||||
|
@ -326,9 +304,10 @@ void BitcoinCore::shutdown()
|
|||
}
|
||||
}
|
||||
|
||||
BitcoinApplication::BitcoinApplication(int &argc, char **argv):
|
||||
BitcoinApplication::BitcoinApplication(interface::Node& node, int &argc, char **argv):
|
||||
QApplication(argc, argv),
|
||||
coreThread(0),
|
||||
m_node(node),
|
||||
optionsModel(0),
|
||||
clientModel(0),
|
||||
window(0),
|
||||
|
@ -409,7 +388,7 @@ void BitcoinApplication::startThread()
|
|||
if(coreThread)
|
||||
return;
|
||||
coreThread = new QThread(this);
|
||||
BitcoinCore *executor = new BitcoinCore();
|
||||
BitcoinCore *executor = new BitcoinCore(m_node);
|
||||
executor->moveToThread(coreThread);
|
||||
|
||||
/* communication to and from thread */
|
||||
|
@ -427,8 +406,8 @@ void BitcoinApplication::startThread()
|
|||
|
||||
void BitcoinApplication::parameterSetup()
|
||||
{
|
||||
InitLogging();
|
||||
InitParameterInteraction();
|
||||
m_node.initLogging();
|
||||
m_node.initParameterInteraction();
|
||||
}
|
||||
|
||||
void BitcoinApplication::requestInitialize()
|
||||
|
@ -461,7 +440,7 @@ void BitcoinApplication::requestShutdown()
|
|||
delete clientModel;
|
||||
clientModel = 0;
|
||||
|
||||
StartShutdown();
|
||||
m_node.startShutdown();
|
||||
|
||||
// Request shutdown from core thread
|
||||
Q_EMIT requestedShutdown();
|
||||
|
@ -555,9 +534,11 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
SetupEnvironment();
|
||||
|
||||
std::unique_ptr<interface::Node> node = interface::MakeNode();
|
||||
|
||||
/// 1. Parse command-line options. These take precedence over anything else.
|
||||
// Command-line options take precedence:
|
||||
gArgs.ParseParameters(argc, argv);
|
||||
node->parseParameters(argc, argv);
|
||||
|
||||
// Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
|
||||
|
||||
|
@ -571,7 +552,7 @@ int main(int argc, char *argv[])
|
|||
Q_INIT_RESOURCE(bitcoin);
|
||||
Q_INIT_RESOURCE(bitcoin_locale);
|
||||
|
||||
BitcoinApplication app(argc, argv);
|
||||
BitcoinApplication app(*node, argc, argv);
|
||||
#if QT_VERSION > 0x050100
|
||||
// Generate high-dpi pixmaps
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
@ -633,7 +614,7 @@ int main(int argc, char *argv[])
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
try {
|
||||
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
|
||||
node->readConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
|
||||
} catch (const std::exception& e) {
|
||||
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
|
||||
QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what()));
|
||||
|
@ -648,7 +629,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
|
||||
try {
|
||||
SelectParams(ChainNameFromCommandLine());
|
||||
node->selectParams(ChainNameFromCommandLine());
|
||||
} catch(std::exception &e) {
|
||||
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what()));
|
||||
return EXIT_FAILURE;
|
||||
|
@ -705,7 +686,7 @@ int main(int argc, char *argv[])
|
|||
app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
|
||||
|
||||
// Subscribe to global signals from core
|
||||
uiInterface.InitMessage.connect(InitMessage);
|
||||
std::unique_ptr<interface::Handler> handler = node->handleInitMessage(InitMessage);
|
||||
|
||||
if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false))
|
||||
app.createSplashScreen(networkStyle.data());
|
||||
|
@ -717,7 +698,7 @@ int main(int argc, char *argv[])
|
|||
// Perform base initialization before spinning up initialization/shutdown thread
|
||||
// This is acceptable because this function only contains steps that are quick to execute,
|
||||
// so the GUI thread won't be held up.
|
||||
if (BitcoinCore::baseInitialize()) {
|
||||
if (node->baseInitialize()) {
|
||||
app.requestInitialize();
|
||||
#if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
|
||||
WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(QObject::tr(PACKAGE_NAME)), (HWND)app.getMainWinId());
|
||||
|
@ -732,10 +713,10 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
} catch (const std::exception& e) {
|
||||
PrintExceptionContinue(&e, "Runaway exception");
|
||||
app.handleRunawayException(QString::fromStdString(GetWarnings("gui")));
|
||||
app.handleRunawayException(QString::fromStdString(node->getWarnings("gui")));
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(nullptr, "Runaway exception");
|
||||
app.handleRunawayException(QString::fromStdString(GetWarnings("gui")));
|
||||
app.handleRunawayException(QString::fromStdString(node->getWarnings("gui")));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue