Skip to content

Commit cbf0093

Browse files
author
MarcoFalke
committed
Merge #14437: Refactor: Start to separate wallet from node
081accb Pass chain locked variables where needed (Russell Yanofsky) 79d579f Remove uses of cs_main in wallet code (Russell Yanofsky) ea961c3 Remove direct node->wallet calls in init.cpp (Russell Yanofsky) 8db11dd Pass chain and client variables where needed (Russell Yanofsky) 7e2e62c Add skeleton chain and client classes (Russell Yanofsky) Pull request description: This creates an incomplete [`Chain`](https://github.com/ryanofsky/bitcoin/blob/pr/wipc-sep/src/interfaces/chain.h) interface in [`src/interfaces/`](https://github.com/ryanofsky/bitcoin/tree/pr/wipc-sep/src/interfaces) and begins to update wallet code to use it. #10973 builds on this, changing the wallet to use the new interface to access chain state, instead of using CBlockIndex pointers and global variables like `chainActive`. Tree-SHA512: 6ef05a4d8ebf57f2ad71835e4d970c9c59e34057e39e48cee76b887492c2fee907e3f6a74a9861e5a9f97cdc6823f4865ebc41ec556ab371ebca1b664c20dbea
2 parents e70a19e + 081accb commit cbf0093

34 files changed

+722
-372
lines changed

build_msvc/msvc-autogen.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
]
1717

1818
ignore_list = [
19-
'rpc/net.cpp',
20-
'interfaces/handler.cpp',
21-
'interfaces/node.cpp',
22-
'interfaces/wallet.cpp',
2319
]
2420

2521
lib_sources = {}
@@ -32,7 +28,9 @@ def parse_makefile(makefile):
3228
if current_lib:
3329
source = line.split()[0]
3430
if source.endswith('.cpp') and not source.startswith('$') and source not in ignore_list:
35-
lib_sources[current_lib].append(source.replace('/', '\\'))
31+
source_filename = source.replace('/', '\\')
32+
object_filename = source.replace('/', '_')[:-4] + ".obj"
33+
lib_sources[current_lib].append((source_filename, object_filename))
3634
if not line.endswith('\\'):
3735
current_lib = ''
3836
continue
@@ -51,8 +49,10 @@ def main():
5149
for key, value in lib_sources.items():
5250
vcxproj_filename = os.path.abspath(os.path.join(os.path.dirname(__file__), key, key + '.vcxproj'))
5351
content = ''
54-
for source_filename in value:
55-
content += ' <ClCompile Include="..\\..\\src\\' + source_filename + '" />\n'
52+
for source_filename, object_filename in value:
53+
content += ' <ClCompile Include="..\\..\\src\\' + source_filename + '">\n'
54+
content += ' <ObjectFileName>$(IntDir)' + object_filename + '</ObjectFileName>\n'
55+
content += ' </ClCompile>\n'
5656
with open(vcxproj_filename + '.in', 'r', encoding='utf-8') as vcxproj_in_file:
5757
with open(vcxproj_filename, 'w', encoding='utf-8') as vcxproj_file:
5858
vcxproj_file.write(vcxproj_in_file.read().replace(

src/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ BITCOIN_CORE_H = \
125125
index/txindex.h \
126126
indirectmap.h \
127127
init.h \
128+
interfaces/chain.h \
128129
interfaces/handler.h \
129130
interfaces/node.h \
130131
interfaces/wallet.h \
@@ -233,6 +234,7 @@ libbitcoin_server_a_SOURCES = \
233234
httpserver.cpp \
234235
index/base.cpp \
235236
index/txindex.cpp \
237+
interfaces/chain.cpp \
236238
interfaces/handler.cpp \
237239
interfaces/node.cpp \
238240
init.cpp \
@@ -465,6 +467,7 @@ endif
465467
bitcoind_LDADD = \
466468
$(LIBBITCOIN_SERVER) \
467469
$(LIBBITCOIN_WALLET) \
470+
$(LIBBITCOIN_SERVER) \
468471
$(LIBBITCOIN_COMMON) \
469472
$(LIBUNIVALUE) \
470473
$(LIBBITCOIN_UTIL) \

src/bench/coin_selection.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <bench/bench.h>
6+
#include <interfaces/chain.h>
67
#include <wallet/wallet.h>
78
#include <wallet/coinselection.h>
89

@@ -33,7 +34,8 @@ static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<Ou
3334
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
3435
static void CoinSelection(benchmark::State& state)
3536
{
36-
const CWallet wallet(WalletLocation(), WalletDatabase::CreateDummy());
37+
auto chain = interfaces::MakeChain();
38+
const CWallet wallet(*chain, WalletLocation(), WalletDatabase::CreateDummy());
3739
LOCK(wallet.cs_wallet);
3840

3941
// Add coins.
@@ -57,7 +59,8 @@ static void CoinSelection(benchmark::State& state)
5759
}
5860

5961
typedef std::set<CInputCoin> CoinSet;
60-
static const CWallet testWallet(WalletLocation(), WalletDatabase::CreateDummy());
62+
static auto testChain = interfaces::MakeChain();
63+
static const CWallet testWallet(*testChain, WalletLocation(), WalletDatabase::CreateDummy());
6164
std::vector<std::unique_ptr<CWalletTx>> wtxn;
6265

6366
// Copied from src/wallet/test/coinselector_tests.cpp

src/bitcoind.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <clientversion.h>
1212
#include <compat.h>
1313
#include <fs.h>
14+
#include <interfaces/chain.h>
1415
#include <rpc/server.h>
1516
#include <init.h>
1617
#include <noui.h>
@@ -58,6 +59,9 @@ static void WaitForShutdown()
5859
//
5960
static bool AppInit(int argc, char* argv[])
6061
{
62+
InitInterfaces interfaces;
63+
interfaces.chain = interfaces::MakeChain();
64+
6165
bool fRet = false;
6266

6367
//
@@ -164,7 +168,7 @@ static bool AppInit(int argc, char* argv[])
164168
// If locking the data directory failed, exit immediately
165169
return false;
166170
}
167-
fRet = AppInitMain();
171+
fRet = AppInitMain(interfaces);
168172
}
169173
catch (const std::exception& e) {
170174
PrintExceptionContinue(&e, "AppInit()");
@@ -178,7 +182,7 @@ static bool AppInit(int argc, char* argv[])
178182
} else {
179183
WaitForShutdown();
180184
}
181-
Shutdown();
185+
Shutdown(interfaces);
182186

183187
return fRet;
184188
}

src/dummywallet.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@ class DummyWalletInit : public WalletInitInterface {
1414
bool HasWalletSupport() const override {return false;}
1515
void AddWalletOptions() const override;
1616
bool ParameterInteraction() const override {return true;}
17-
void RegisterRPC(CRPCTable &) const override {}
18-
bool Verify() const override {return true;}
19-
bool Open() const override {LogPrintf("No wallet support compiled in!\n"); return true;}
20-
void Start(CScheduler& scheduler) const override {}
21-
void Flush() const override {}
22-
void Stop() const override {}
23-
void Close() const override {}
17+
void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
2418
};
2519

2620
void DummyWalletInit::AddWalletOptions() const

src/init.cpp

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <fs.h>
2020
#include <httpserver.h>
2121
#include <httprpc.h>
22+
#include <interfaces/chain.h>
2223
#include <index/txindex.h>
2324
#include <key.h>
2425
#include <validation.h>
@@ -32,6 +33,7 @@
3233
#include <rpc/server.h>
3334
#include <rpc/register.h>
3435
#include <rpc/blockchain.h>
36+
#include <rpc/util.h>
3537
#include <script/standard.h>
3638
#include <script/sigcache.h>
3739
#include <scheduler.h>
@@ -157,7 +159,7 @@ void Interrupt()
157159
}
158160
}
159161

160-
void Shutdown()
162+
void Shutdown(InitInterfaces& interfaces)
161163
{
162164
LogPrintf("%s: In progress...\n", __func__);
163165
static CCriticalSection cs_Shutdown;
@@ -176,7 +178,9 @@ void Shutdown()
176178
StopREST();
177179
StopRPC();
178180
StopHTTPServer();
179-
g_wallet_init_interface.Flush();
181+
for (const auto& client : interfaces.chain_clients) {
182+
client->flush();
183+
}
180184
StopMapPort();
181185

182186
// Because these depend on each-other, we make sure that neither can be
@@ -239,7 +243,9 @@ void Shutdown()
239243
pcoinsdbview.reset();
240244
pblocktree.reset();
241245
}
242-
g_wallet_init_interface.Stop();
246+
for (const auto& client : interfaces.chain_clients) {
247+
client->stop();
248+
}
243249

244250
#if ENABLE_ZMQ
245251
if (g_zmq_notification_interface) {
@@ -259,7 +265,7 @@ void Shutdown()
259265
UnregisterAllValidationInterfaces();
260266
GetMainSignals().UnregisterBackgroundSignalScheduler();
261267
GetMainSignals().UnregisterWithMempoolSignals(mempool);
262-
g_wallet_init_interface.Close();
268+
interfaces.chain_clients.clear();
263269
globalVerifyHandle.reset();
264270
ECC_Stop();
265271
LogPrintf("%s: done\n", __func__);
@@ -1158,7 +1164,7 @@ bool AppInitLockDataDirectory()
11581164
return true;
11591165
}
11601166

1161-
bool AppInitMain()
1167+
bool AppInitMain(InitInterfaces& interfaces)
11621168
{
11631169
const CChainParams& chainparams = Params();
11641170
// ********************************************************* Step 4a: application initialization
@@ -1221,11 +1227,20 @@ bool AppInitMain()
12211227
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
12221228
GetMainSignals().RegisterWithMempoolSignals(mempool);
12231229

1230+
// Create client interfaces for wallets that are supposed to be loaded
1231+
// according to -wallet and -disablewallet options. This only constructs
1232+
// the interfaces, it doesn't load wallet data. Wallets actually get loaded
1233+
// when load() and start() interface methods are called below.
1234+
g_wallet_init_interface.Construct(interfaces);
1235+
12241236
/* Register RPC commands regardless of -server setting so they will be
12251237
* available in the GUI RPC console even if external calls are disabled.
12261238
*/
12271239
RegisterAllCoreRPCCommands(tableRPC);
1228-
g_wallet_init_interface.RegisterRPC(tableRPC);
1240+
for (const auto& client : interfaces.chain_clients) {
1241+
client->registerRpcs();
1242+
}
1243+
g_rpc_interfaces = &interfaces;
12291244
#if ENABLE_ZMQ
12301245
RegisterZMQRPCCommands(tableRPC);
12311246
#endif
@@ -1243,7 +1258,11 @@ bool AppInitMain()
12431258
}
12441259

12451260
// ********************************************************* Step 5: verify wallet database integrity
1246-
if (!g_wallet_init_interface.Verify()) return false;
1261+
for (const auto& client : interfaces.chain_clients) {
1262+
if (!client->verify()) {
1263+
return false;
1264+
}
1265+
}
12471266

12481267
// ********************************************************* Step 6: network initialization
12491268
// Note that we absolutely cannot open any actual connections
@@ -1562,7 +1581,11 @@ bool AppInitMain()
15621581
}
15631582

15641583
// ********************************************************* Step 9: load wallet
1565-
if (!g_wallet_init_interface.Open()) return false;
1584+
for (const auto& client : interfaces.chain_clients) {
1585+
if (!client->load()) {
1586+
return false;
1587+
}
1588+
}
15661589

15671590
// ********************************************************* Step 10: data directory maintenance
15681591

@@ -1708,7 +1731,9 @@ bool AppInitMain()
17081731
SetRPCWarmupFinished();
17091732
uiInterface.InitMessage(_("Done loading"));
17101733

1711-
g_wallet_init_interface.Start(scheduler);
1734+
for (const auto& client : interfaces.chain_clients) {
1735+
client->start(scheduler);
1736+
}
17121737

17131738
return true;
17141739
}

src/init.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@
1010
#include <string>
1111
#include <util/system.h>
1212

13-
class CScheduler;
14-
class CWallet;
13+
namespace interfaces {
14+
class Chain;
15+
class ChainClient;
16+
} // namespace interfaces
17+
18+
//! Pointers to interfaces used during init and destroyed on shutdown.
19+
struct InitInterfaces
20+
{
21+
std::unique_ptr<interfaces::Chain> chain;
22+
std::vector<std::unique_ptr<interfaces::ChainClient>> chain_clients;
23+
};
1524

1625
namespace boost
1726
{
@@ -20,7 +29,7 @@ class thread_group;
2029

2130
/** Interrupt threads */
2231
void Interrupt();
23-
void Shutdown();
32+
void Shutdown(InitInterfaces& interfaces);
2433
//!Initialize the logging infrastructure
2534
void InitLogging();
2635
//!Parameter interaction: change current parameters depending on various rules
@@ -54,7 +63,7 @@ bool AppInitLockDataDirectory();
5463
* @note This should only be done after daemonization. Call Shutdown() if this function fails.
5564
* @pre Parameters should be parsed and config file should be read, AppInitLockDataDirectory should have been called.
5665
*/
57-
bool AppInitMain();
66+
bool AppInitMain(InitInterfaces& interfaces);
5867

5968
/**
6069
* Setup the arguments for gArgs

src/interfaces/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The following interfaces are defined here:
44

55
* [`Chain`](chain.h) — used by wallet to access blockchain and mempool state. Added in [#10973](https://github.com/bitcoin/bitcoin/pull/10973).
66

7-
* [`Chain::Client`](chain.h) — used by node to start & stop `Chain` clients. Added in [#10973](https://github.com/bitcoin/bitcoin/pull/10973).
7+
* [`ChainClient`](chain.h) — used by node to start & stop `Chain` clients. Added in [#10973](https://github.com/bitcoin/bitcoin/pull/10973).
88

99
* [`Node`](node.h) — used by GUI to start & stop bitcoin node. Added in [#10244](https://github.com/bitcoin/bitcoin/pull/10244).
1010

src/interfaces/chain.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) 2018 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <interfaces/chain.h>
6+
7+
#include <sync.h>
8+
#include <util/system.h>
9+
#include <validation.h>
10+
11+
#include <memory>
12+
#include <utility>
13+
14+
namespace interfaces {
15+
namespace {
16+
17+
class LockImpl : public Chain::Lock
18+
{
19+
};
20+
21+
class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>
22+
{
23+
using UniqueLock::UniqueLock;
24+
};
25+
26+
class ChainImpl : public Chain
27+
{
28+
public:
29+
std::unique_ptr<Chain::Lock> lock(bool try_lock) override
30+
{
31+
auto result = MakeUnique<LockingStateImpl>(::cs_main, "cs_main", __FILE__, __LINE__, try_lock);
32+
if (try_lock && result && !*result) return {};
33+
// std::move necessary on some compilers due to conversion from
34+
// LockingStateImpl to Lock pointer
35+
return std::move(result);
36+
}
37+
std::unique_ptr<Chain::Lock> assumeLocked() override { return MakeUnique<LockImpl>(); }
38+
};
39+
40+
} // namespace
41+
42+
std::unique_ptr<Chain> MakeChain() { return MakeUnique<ChainImpl>(); }
43+
44+
} // namespace interfaces

0 commit comments

Comments
 (0)