Skip to content

Commit 1407a2b

Browse files
committed
Add ipc::Node and ipc::Wallet interfaces
Port bitcoin-qt code to access node and wallet functionality through new abstract interfaces `ipc::Node` and `ipc::Wallet` instead of directly calling libbitcoin functions. A future commit will add new implementations of these interfaces that move the functionality to separate process accessed over an IPC socket.
1 parent 2073550 commit 1407a2b

26 files changed

+494
-131
lines changed

src/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ BITCOIN_CORE_H = \
103103
httpserver.h \
104104
indirectmap.h \
105105
init.h \
106+
ipc/interfaces.h \
107+
ipc/util.h \
106108
key.h \
107109
keystore.h \
108110
dbwrapper.h \
@@ -330,6 +332,7 @@ libbitcoin_util_a_SOURCES = \
330332
compat/glibcxx_sanity.cpp \
331333
compat/strnlen.cpp \
332334
fs.cpp \
335+
ipc/interfaces.cpp \
333336
random.cpp \
334337
rpc/protocol.cpp \
335338
support/cleanse.cpp \

src/ipc/interfaces.cpp

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include <ipc/interfaces.h>
2+
3+
#include <chain.h>
4+
#include <chainparams.h>
5+
#include <init.h>
6+
#include <ipc/util.h>
7+
#include <net.h>
8+
#include <net_processing.h>
9+
#include <scheduler.h>
10+
#include <ui_interface.h>
11+
#include <util.h>
12+
#include <validation.h>
13+
#include <wallet/wallet.h>
14+
15+
#include <boost/thread.hpp>
16+
17+
namespace ipc {
18+
namespace {
19+
20+
class HandlerImpl : public Handler
21+
{
22+
public:
23+
HandlerImpl(boost::signals2::connection connection) : connection(std::move(connection)) {}
24+
void disconnect() override { connection.disconnect(); }
25+
boost::signals2::scoped_connection connection;
26+
};
27+
28+
class WalletImpl : public Wallet
29+
{
30+
public:
31+
WalletImpl(CWallet& wallet) : wallet(wallet) {}
32+
CAmount getBalance() override { return wallet.GetBalance(); }
33+
CWallet& wallet;
34+
};
35+
36+
class NodeImpl : public Node
37+
{
38+
public:
39+
void parseParameters(int argc, const char* const argv[]) override { ::ParseParameters(argc, argv); }
40+
void softSetArg(const std::string& arg, const std::string& value) override { ::SoftSetArg(arg, value); }
41+
void softSetBoolArg(const std::string& arg, bool value) override { ::SoftSetBoolArg(arg, value); }
42+
void readConfigFile(const std::string& confPath) override { ::ReadConfigFile(confPath); }
43+
void selectParams(const std::string& network) override { ::SelectParams(network); }
44+
bool appInit() override
45+
{
46+
return ::AppInitBasicSetup() && ::AppInitParameterInteraction() && ::AppInitSanityChecks() &&
47+
::AppInitMain(threadGroup, scheduler);
48+
}
49+
void appShutdown() override
50+
{
51+
::Interrupt(threadGroup);
52+
threadGroup.join_all();
53+
::Shutdown();
54+
}
55+
bool shutdownRequested() override { return ::ShutdownRequested(); }
56+
std::string helpMessage(HelpMessageMode mode) override { return ::HelpMessage(mode); }
57+
std::unique_ptr<Wallet> getWallet() override { return util::MakeUnique<WalletImpl>(*pwalletMain); }
58+
std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override
59+
{
60+
return util::MakeUnique<HandlerImpl>(uiInterface.ThreadSafeMessageBox.connect(fn));
61+
}
62+
std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override
63+
{
64+
return util::MakeUnique<HandlerImpl>(uiInterface.ThreadSafeQuestion.connect(fn));
65+
}
66+
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
67+
{
68+
return util::MakeUnique<HandlerImpl>(uiInterface.InitMessage.connect(fn));
69+
}
70+
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
71+
{
72+
return util::MakeUnique<HandlerImpl>(uiInterface.NotifyNumConnectionsChanged.connect(fn));
73+
}
74+
std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) override
75+
{
76+
return util::MakeUnique<HandlerImpl>(uiInterface.NotifyNetworkActiveChanged.connect(fn));
77+
}
78+
std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) override
79+
{
80+
return util::MakeUnique<HandlerImpl>(uiInterface.NotifyAlertChanged.connect(fn));
81+
}
82+
std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
83+
{
84+
return util::MakeUnique<HandlerImpl>(uiInterface.ShowProgress.connect(fn));
85+
}
86+
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
87+
{
88+
return util::MakeUnique<HandlerImpl>(
89+
uiInterface.NotifyBlockTip.connect([fn](bool initialDownload, const CBlockIndex* block) {
90+
fn(initialDownload, block->nHeight, block->GetBlockTime(),
91+
GuessVerificationProgress(Params().TxData(), block));
92+
}));
93+
}
94+
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
95+
{
96+
return util::MakeUnique<HandlerImpl>(
97+
uiInterface.NotifyHeaderTip.connect([fn](bool initialDownload, const CBlockIndex* block) {
98+
fn(initialDownload, block->nHeight, block->GetBlockTime(),
99+
GuessVerificationProgress(Params().TxData(), block));
100+
}));
101+
}
102+
std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) override
103+
{
104+
return util::MakeUnique<HandlerImpl>(uiInterface.BannedListChanged.connect(fn));
105+
}
106+
bool getNodesStats(NodesStats& stats) override
107+
{
108+
stats.clear();
109+
110+
if (g_connman) {
111+
std::vector<CNodeStats> statsTemp;
112+
g_connman->GetNodeStats(statsTemp);
113+
114+
stats.reserve(statsTemp.size());
115+
for (auto& nodeStatsTemp : statsTemp) {
116+
stats.emplace_back(std::move(nodeStatsTemp), false, CNodeStateStats());
117+
}
118+
119+
// Try to retrieve the CNodeStateStats for each node.
120+
TRY_LOCK(cs_main, lockMain);
121+
if (lockMain) {
122+
for (auto& nodeStats : stats) {
123+
std::get<1>(nodeStats) = GetNodeStateStats(std::get<0>(nodeStats).nodeid, std::get<2>(nodeStats));
124+
}
125+
}
126+
return true;
127+
}
128+
return false;
129+
}
130+
bool getBanned(banmap_t& banMap)
131+
{
132+
if (g_connman) {
133+
g_connman->GetBanned(banMap);
134+
return true;
135+
}
136+
return false;
137+
}
138+
139+
boost::thread_group threadGroup;
140+
::CScheduler scheduler;
141+
};
142+
143+
} // namespace
144+
145+
std::unique_ptr<Node> MakeNode() { return util::MakeUnique<NodeImpl>(); }
146+
147+
} // namespace ipc

src/ipc/interfaces.h

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,136 @@
11
#ifndef BITCOIN_IPC_INTERFACES_H
22
#define BITCOIN_IPC_INTERFACES_H
33

4+
#include "addrdb.h" // For banmap_t
5+
#include "amount.h" // For CAmount
6+
#include "init.h" // For HelpMessageMode
7+
8+
#include <memory>
9+
#include <tuple>
410
#include <type_traits>
11+
#include <vector>
12+
13+
class CNodeStats;
14+
struct CNodeStateStats;
15+
16+
namespace ipc {
17+
18+
class Node;
19+
class Wallet;
20+
class Handler;
21+
22+
//! Top-level interface for a bitcoin node (bitcoind process).
23+
class Node
24+
{
25+
public:
26+
virtual ~Node() {}
27+
28+
//! Set command line arguments.
29+
virtual void parseParameters(int argc, const char* const argv[]) = 0;
30+
31+
//! Set a command line argument if it doesn't already have a value
32+
virtual void softSetArg(const std::string& arg, const std::string& value) = 0;
33+
34+
//! Set a command line boolean argument if it doesn't already have a value
35+
virtual void softSetBoolArg(const std::string& arg, bool value) = 0;
36+
37+
//! Load settings from configuration file.
38+
virtual void readConfigFile(const std::string& confPath) = 0;
39+
40+
//! Choose network parameters.
41+
virtual void selectParams(const std::string& network) = 0;
42+
43+
//! Start node.
44+
virtual bool appInit() = 0;
45+
46+
//! Stop node.
47+
virtual void appShutdown() = 0;
48+
49+
//! Return whether shutdown was requested.
50+
virtual bool shutdownRequested() = 0;
51+
52+
//! Get help message string.
53+
virtual std::string helpMessage(HelpMessageMode mode) = 0;
54+
55+
//! Return interface for accessing the wallet.
56+
virtual std::unique_ptr<Wallet> getWallet() = 0;
57+
58+
//! Register handler for message box messages.
59+
using MessageBoxFn =
60+
std::function<bool(const std::string& message, const std::string& caption, unsigned int style)>;
61+
virtual std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) = 0;
62+
63+
//! Register handler for question messages.
64+
using QuestionFn = std::function<bool(const std::string& message,
65+
const std::string& nonInteractiveMessage,
66+
const std::string& caption,
67+
unsigned int style)>;
68+
virtual std::unique_ptr<Handler> handleQuestion(QuestionFn fn) = 0;
69+
70+
//! Register handler for init messages.
71+
using InitMessageFn = std::function<void(const std::string& message)>;
72+
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
73+
74+
//! Register handler for number of connections changed messages.
75+
using NotifyNumConnectionsChangedFn = std::function<void(int newNumConnections)>;
76+
virtual std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) = 0;
77+
78+
//! Register handler for network active messages.
79+
using NotifyNetworkActiveChangedFn = std::function<void(bool networkActive)>;
80+
virtual std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) = 0;
81+
82+
//! Register handler for notify alert messages.
83+
using NotifyAlertChangedFn = std::function<void()>;
84+
virtual std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) = 0;
85+
86+
//! Register handler for progress messages.
87+
using ShowProgressFn = std::function<void(const std::string& title, int progress)>;
88+
virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0;
89+
90+
//! Register handler for block tip messages.
91+
using NotifyBlockTipFn =
92+
std::function<void(bool initialDownload, int height, int64_t blockTime, double verificationProgress)>;
93+
virtual std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) = 0;
94+
95+
//! Register handler for header tip messages.
96+
using NotifyHeaderTipFn =
97+
std::function<void(bool initialDownload, int height, int64_t blockTime, double verificationProgress)>;
98+
virtual std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) = 0;
99+
100+
//! Register handler for ban list messages.
101+
using BannedListChangedFn = std::function<void()>;
102+
virtual std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) = 0;
103+
104+
//! Get stats for connected nodes.
105+
using NodesStats = std::vector<std::tuple<CNodeStats, bool, CNodeStateStats>>;
106+
virtual bool getNodesStats(NodesStats& stats) = 0;
107+
108+
//! Get ban map entries.
109+
virtual bool getBanned(banmap_t& banMap) = 0;
110+
};
111+
112+
//! Interface for accessing a wallet.
113+
class Wallet
114+
{
115+
public:
116+
virtual ~Wallet() {}
117+
//! Return wallet balance.
118+
virtual CAmount getBalance() = 0;
119+
};
120+
121+
//! Interface for managing a registered handler.
122+
class Handler
123+
{
124+
public:
125+
virtual ~Handler() {}
126+
//! Disconnect the handler.
127+
virtual void disconnect() = 0;
128+
};
129+
130+
//! Construct Node object.
131+
std::unique_ptr<Node> MakeNode();
132+
133+
} // namespace ipc
5134

6135
#define ENABLE_IPC 1
7136
#if ENABLE_IPC

src/ipc/util.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef BITCOIN_IPC_UTIL_H
2+
#define BITCOIN_IPC_UTIL_H
3+
4+
namespace ipc {
5+
namespace util {
6+
7+
//! Substitute for for C++14 std::make_unique.
8+
template <typename T, typename... Args>
9+
std::unique_ptr<T> MakeUnique(Args&&... args)
10+
{
11+
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
12+
}
13+
14+
} // namespace util
15+
} // namespace ipc
16+
17+
#endif // BITCOIN_IPC_UTIL_H

src/net_processing.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ class PeerLogicValidation : public CValidationInterface {
3737
};
3838

3939
struct CNodeStateStats {
40-
int nMisbehavior;
41-
int nSyncHeight;
42-
int nCommonHeight;
40+
int nMisbehavior = 0;
41+
int nSyncHeight = -1;
42+
int nCommonHeight = -1;
4343
std::vector<int> vHeightInFlight;
4444
};
4545

src/qt/bantablemodel.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ class BanTablePriv
4646
Qt::SortOrder sortOrder;
4747

4848
/** Pull a full list of banned nodes from CNode into our cache */
49-
void refreshBanlist()
49+
void refreshBanlist(ipc::Node& ipcNode)
5050
{
5151
banmap_t banMap;
52-
if(FIXME_IMPLEMENT_IPC_VALUE(g_connman))
53-
FIXME_IMPLEMENT_IPC_VALUE(g_connman)->GetBanned(banMap);
52+
ipcNode.getBanned(banMap);
5453

5554
cachedBanlist.clear();
5655
#if QT_VERSION >= 0x040700
@@ -83,8 +82,9 @@ class BanTablePriv
8382
}
8483
};
8584

86-
BanTableModel::BanTableModel(ClientModel *parent) :
85+
BanTableModel::BanTableModel(ipc::Node& ipcNode, ClientModel *parent) :
8786
QAbstractTableModel(parent),
87+
ipcNode(ipcNode),
8888
clientModel(parent)
8989
{
9090
columns << tr("IP/Netmask") << tr("Banned Until");
@@ -169,7 +169,7 @@ QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent)
169169
void BanTableModel::refresh()
170170
{
171171
Q_EMIT layoutAboutToBeChanged();
172-
priv->refreshBanlist();
172+
priv->refreshBanlist(ipcNode);
173173
Q_EMIT layoutChanged();
174174
}
175175

src/qt/bantablemodel.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
class ClientModel;
1414
class BanTablePriv;
1515

16+
namespace ipc {
17+
class Node;
18+
}
19+
1620
struct CCombinedBan {
1721
CSubNet subnet;
1822
CBanEntry banEntry;
@@ -39,7 +43,7 @@ class BanTableModel : public QAbstractTableModel
3943
Q_OBJECT
4044

4145
public:
42-
explicit BanTableModel(ClientModel *parent = 0);
46+
explicit BanTableModel(ipc::Node& ipcNode, ClientModel *parent = 0);
4347
~BanTableModel();
4448
void startAutoRefresh();
4549
void stopAutoRefresh();
@@ -65,6 +69,7 @@ public Q_SLOTS:
6569
void refresh();
6670

6771
private:
72+
ipc::Node& ipcNode;
6873
ClientModel *clientModel;
6974
QStringList columns;
7075
std::unique_ptr<BanTablePriv> priv;

0 commit comments

Comments
 (0)