Skip to content

Commit e4e6d9b

Browse files
Merge #6213: backport: trivial 2024 08 14
c8092fb Merge bitcoin#25214: multiprocess build fix: ipc/capnp/init.capnp.h: No such file or directory (fanquake) 1c40b5d Merge bitcoin#25088: Wallet: Ensure m_attaching_chain is set before registering for signals (Andrew Chow) 247fe41 Merge bitcoin#24984: wallet: ignore chainStateFlushed notifications while attaching chain (Andrew Chow) 93e7c38 Merge bitcoin#24338: util: Work around libstdc++ create_directories issue (fanquake) e80c2a3 Merge bitcoin#24308: util: use stronger-guarantee rename method (MarcoFalke) f3775d9 Merge bitcoin#24251: Re-enable windows path tests disabled by bitcoin#20744 (fanquake) f2f2982 Merge bitcoin#23707: fuzz: Fix RPC internal bug detection (MarcoFalke) d06b693 Merge bitcoin#23654: fuzz: Rework rpc fuzz target (MarcoFalke) e45229d Merge bitcoin#23385: refactor: get wallet path relative to wallet_dir (fanquake) 9d9d97d Merge bitcoin#22218: multiprocess: Add ipc::Context and ipc::capnp::Context structs (MarcoFalke) Pull request description: ## Issue being fixed or feature implemented Batch of trivial backports ## What was done? ## How Has This Been Tested? Built and tests locally ## Breaking Changes ## Checklist: _Go over all the following points, and put an `x` in all the boxes that apply._ - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: knst: utACK c8092fb UdjinM6: utACK c8092fb Tree-SHA512: 7e3f95737b8c945e737396f130cddca24f71aa4d7f5ccb8ead62b8ba90e187af7036c1be0984e7f000a058606cc74e5381768dc2aad6e56d07a8238934198dcc
2 parents c8734e2 + c8092fb commit e4e6d9b

22 files changed

+199
-34
lines changed

src/Makefile.am

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@ obj/build.h: FORCE
410410
"$(abs_top_srcdir)"
411411
libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
412412

413-
ipc/capnp/libbitcoin_ipc_a-ipc.$(OBJEXT): $(libbitcoin_ipc_mpgen_input:=.h)
414413

415414
# server: shared between dashd and dash-qt
416415
# Contains code accessing mempool and chain state that is meant to be separated
@@ -1015,12 +1014,18 @@ libbitcoin_ipc_mpgen_input = \
10151014
EXTRA_DIST += $(libbitcoin_ipc_mpgen_input)
10161015
%.capnp:
10171016

1017+
# Explicitly list dependencies on generated headers as described in
1018+
# https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html#Recording-Dependencies-manually
1019+
ipc/capnp/libbitcoin_ipc_a-protocol.$(OBJEXT): $(libbitcoin_ipc_mpgen_input:=.h)
1020+
10181021
if BUILD_MULTIPROCESS
10191022
LIBBITCOIN_IPC=libbitcoin_ipc.a
10201023
libbitcoin_ipc_a_SOURCES = \
1024+
ipc/capnp/context.h \
10211025
ipc/capnp/init-types.h \
10221026
ipc/capnp/protocol.cpp \
10231027
ipc/capnp/protocol.h \
1028+
ipc/context.h \
10241029
ipc/exception.h \
10251030
ipc/interfaces.cpp \
10261031
ipc/process.cpp \

src/fs.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,28 @@ static inline path PathFromString(const std::string& string)
158158
return std::filesystem::path(string);
159159
#endif
160160
}
161+
162+
/**
163+
* Create directory (and if necessary its parents), unless the leaf directory
164+
* already exists or is a symlink to an existing directory.
165+
* This is a temporary workaround for an issue in libstdc++ that has been fixed
166+
* upstream [PR101510].
167+
*/
168+
static inline bool create_directories(const std::filesystem::path& p)
169+
{
170+
if (std::filesystem::is_symlink(p) && std::filesystem::is_directory(p)) {
171+
return false;
172+
}
173+
return std::filesystem::create_directories(p);
174+
}
175+
176+
/**
177+
* This variant is not used. Delete it to prevent it from accidentally working
178+
* around the workaround. If it is needed, add a workaround in the same pattern
179+
* as above.
180+
*/
181+
bool create_directories(const std::filesystem::path& p, std::error_code& ec) = delete;
182+
161183
} // namespace fs
162184

163185
/** Bridge operations to C stdio */

src/interfaces/ipc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include <memory>
1010
#include <typeindex>
1111

12+
namespace ipc {
13+
struct Context;
14+
} // namespace ipc
15+
1216
namespace interfaces {
1317
class Init;
1418

@@ -58,6 +62,9 @@ class Ipc
5862
addCleanup(typeid(Interface), &iface, std::move(cleanup));
5963
}
6064

65+
//! IPC context struct accessor (see struct definition for more description).
66+
virtual ipc::Context& context() = 0;
67+
6168
protected:
6269
//! Internal implementation of public addCleanup method (above) as a
6370
//! type-erased virtual function, since template functions can't be virtual.

src/ipc/capnp/context.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2021 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+
#ifndef BITCOIN_IPC_CAPNP_CONTEXT_H
6+
#define BITCOIN_IPC_CAPNP_CONTEXT_H
7+
8+
#include <ipc/context.h>
9+
10+
namespace ipc {
11+
namespace capnp {
12+
//! Cap'n Proto context struct. Generally the parent ipc::Context struct should
13+
//! be used instead of this struct to give all IPC protocols access to
14+
//! application state, so there aren't unnecessary differences between IPC
15+
//! protocols. But this specialized struct can be used to pass capnp-specific
16+
//! function and object types to capnp hooks.
17+
struct Context : ipc::Context
18+
{
19+
};
20+
} // namespace capnp
21+
} // namespace ipc
22+
23+
#endif // BITCOIN_IPC_CAPNP_CONTEXT_H

src/ipc/capnp/protocol.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 <interfaces/init.h>
6+
#include <ipc/capnp/context.h>
67
#include <ipc/capnp/init.capnp.h>
78
#include <ipc/capnp/init.capnp.proxy.h>
89
#include <ipc/capnp/protocol.h>
@@ -54,7 +55,7 @@ class CapnpProtocol : public Protocol
5455
{
5556
assert(!m_loop);
5657
mp::g_thread_context.thread_name = mp::ThreadName(exe_name);
57-
m_loop.emplace(exe_name, &IpcLogFn, nullptr);
58+
m_loop.emplace(exe_name, &IpcLogFn, &m_context);
5859
mp::ServeStream<messages::Init>(*m_loop, fd, init);
5960
m_loop->loop();
6061
m_loop.reset();
@@ -63,13 +64,14 @@ class CapnpProtocol : public Protocol
6364
{
6465
mp::ProxyTypeRegister::types().at(type)(iface).cleanup.emplace_back(std::move(cleanup));
6566
}
67+
Context& context() override { return m_context; }
6668
void startLoop(const char* exe_name)
6769
{
6870
if (m_loop) return;
6971
std::promise<void> promise;
7072
m_loop_thread = std::thread([&] {
7173
util::ThreadRename("capnp-loop");
72-
m_loop.emplace(exe_name, &IpcLogFn, nullptr);
74+
m_loop.emplace(exe_name, &IpcLogFn, &m_context);
7375
{
7476
std::unique_lock<std::mutex> lock(m_loop->m_mutex);
7577
m_loop->addClient(lock);
@@ -80,6 +82,7 @@ class CapnpProtocol : public Protocol
8082
});
8183
promise.get_future().wait();
8284
}
85+
Context m_context;
8386
std::thread m_loop_thread;
8487
std::optional<mp::EventLoop> m_loop;
8588
};

src/ipc/context.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2021 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+
#ifndef BITCOIN_IPC_CONTEXT_H
6+
#define BITCOIN_IPC_CONTEXT_H
7+
8+
namespace ipc {
9+
//! Context struct used to give IPC protocol implementations or implementation
10+
//! hooks access to application state, in case they need to run extra code that
11+
//! isn't needed within a single process, like code copying global state from an
12+
//! existing process to a new process when it's initialized, or code dealing
13+
//! with shared objects that are created or destroyed remotely.
14+
struct Context
15+
{
16+
};
17+
} // namespace ipc
18+
19+
#endif // BITCOIN_IPC_CONTEXT_H

src/ipc/interfaces.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class IpcImpl : public interfaces::Ipc
6060
{
6161
m_protocol->addCleanup(type, iface, std::move(cleanup));
6262
}
63+
Context& context() override { return m_protocol->context(); }
6364
const char* m_exe_name;
6465
const char* m_process_argv0;
6566
interfaces::Init& m_init;

src/ipc/protocol.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <typeindex>
1313

1414
namespace ipc {
15+
struct Context;
16+
1517
//! IPC protocol interface for calling IPC methods over sockets.
1618
//!
1719
//! There may be different implementations of this interface for different IPC
@@ -33,6 +35,9 @@ class Protocol
3335
//! Add cleanup callback to interface that will run when the interface is
3436
//! deleted.
3537
virtual void addCleanup(std::type_index type, void* iface, std::function<void()> cleanup) = 0;
38+
39+
//! Context accessor.
40+
virtual Context& context() = 0;
3641
};
3742
} // namespace ipc
3843

src/test/dbwrapper_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
203203
{
204204
// We're going to share this fs::path between two wrappers
205205
fs::path ph = m_args.GetDataDirBase() / "existing_data_no_obfuscate";
206-
create_directories(ph);
206+
fs::create_directories(ph);
207207

208208
// Set up a non-obfuscated wrapper to write some initial data.
209209
std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false);
@@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex)
244244
{
245245
// We're going to share this fs::path between two wrappers
246246
fs::path ph = m_args.GetDataDirBase() / "existing_data_reindex";
247-
create_directories(ph);
247+
fs::create_directories(ph);
248248

249249
// Set up a non-obfuscated wrapper to write some initial data.
250250
std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false);

src/test/fs_tests.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,29 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream)
118118
}
119119
}
120120

121+
#ifndef WIN32
122+
BOOST_AUTO_TEST_CASE(create_directories)
123+
{
124+
// Test fs::create_directories workaround.
125+
const fs::path tmpfolder{m_args.GetDataDirBase()};
126+
127+
const fs::path dir{GetUniquePath(tmpfolder)};
128+
fs::create_directory(dir);
129+
BOOST_CHECK(fs::exists(dir));
130+
BOOST_CHECK(fs::is_directory(dir));
131+
BOOST_CHECK(!fs::create_directories(dir));
132+
133+
const fs::path symlink{GetUniquePath(tmpfolder)};
134+
fs::create_directory_symlink(dir, symlink);
135+
BOOST_CHECK(fs::exists(symlink));
136+
BOOST_CHECK(fs::is_symlink(symlink));
137+
BOOST_CHECK(fs::is_directory(symlink));
138+
BOOST_CHECK(!fs::create_directories(symlink));
139+
140+
fs::remove(symlink);
141+
fs::remove(dir);
142+
}
143+
#endif // WIN32
144+
121145
BOOST_AUTO_TEST_SUITE_END()
122146

0 commit comments

Comments
 (0)