mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-17 17:02:43 +00:00
Merge bitcoin/bitcoin#33867: kernel: handle null or empty directories in implementation
6657bcbdb4d0359c1843ca31fb3670c7c0c260d5 kernel: allow null data_directory (stickies-v)
Pull request description:
An empty path may be represented with a `nullptr`. For example, `std::string_view{}.data()` may return nullptr.
Removes the `BITCOINKERNEL_ARG_NONNULL` attribute for `btck_chainstate_manager_options_create` 's `data_directory` parameter, and instead handles such null arguments in the implementation. [Because an empty path is meaningless](https://github.com/bitcoin/bitcoin/pull/33867#discussion_r2523930442), `btck_chainstate_manager_options_create` now treats both null and empty directories as invalid, tightening the interface.
Also documents how `BITCOINKERNEL_ARG_NONNULL` should be used.
Follow-up to https://github.com/bitcoin/bitcoin/pull/33853#pullrequestreview-3454620265
ACKs for top commit:
stringintech:
ACK 6657bcb
maflcko:
review ACK 6657bcbdb4d0359c1843ca31fb3670c7c0c260d5 🐪
achow101:
ACK 6657bcbdb4d0359c1843ca31fb3670c7c0c260d5
TheCharlatan:
ACK 6657bcbdb4d0359c1843ca31fb3670c7c0c260d5
janb84:
ACK 6657bcbdb4d0359c1843ca31fb3670c7c0c260d5
Tree-SHA512: 11c02b221ff19a5357e94355808e3b503b3a336c16fc5186c9c9137931709e880383ed1f4990fc4cc6b0e23961e2e1e03fc90154a3b546b9490ef66bd63688b7
This commit is contained in:
commit
27ac11ea0a
@ -896,6 +896,10 @@ btck_BlockValidationResult btck_block_validation_state_get_block_validation_resu
|
||||
|
||||
btck_ChainstateManagerOptions* btck_chainstate_manager_options_create(const btck_Context* context, const char* data_dir, size_t data_dir_len, const char* blocks_dir, size_t blocks_dir_len)
|
||||
{
|
||||
if (data_dir == nullptr || data_dir_len == 0 || blocks_dir == nullptr || blocks_dir_len == 0) {
|
||||
LogError("Failed to create chainstate manager options: dir must be non-null and non-empty");
|
||||
return nullptr;
|
||||
}
|
||||
try {
|
||||
fs::path abs_data_dir{fs::absolute(fs::PathFromString({data_dir, data_dir_len}))};
|
||||
fs::create_directories(abs_data_dir);
|
||||
|
||||
@ -35,6 +35,17 @@
|
||||
#else
|
||||
#define BITCOINKERNEL_WARN_UNUSED_RESULT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BITCOINKERNEL_ARG_NONNULL is a compiler attribute used to indicate that
|
||||
* certain pointer arguments to a function are not expected to be null.
|
||||
*
|
||||
* Callers must not pass a null pointer for arguments marked with this attribute,
|
||||
* as doing so may result in undefined behavior. This attribute should only be
|
||||
* used for arguments where a null pointer is unambiguously a programmer error,
|
||||
* such as for opaque handles, and not for pointers to raw input data that might
|
||||
* validly be null (e.g., from an empty std::span or std::string).
|
||||
*/
|
||||
#if !defined(BITCOINKERNEL_BUILD) && defined(__GNUC__)
|
||||
#define BITCOINKERNEL_ARG_NONNULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
|
||||
#else
|
||||
@ -933,11 +944,12 @@ BITCOINKERNEL_API const btck_BlockHash* BITCOINKERNEL_WARN_UNUSED_RESULT btck_bl
|
||||
* @brief Create options for the chainstate manager.
|
||||
*
|
||||
* @param[in] context Non-null, the created options and through it the chainstate manager will
|
||||
associate with this kernel context for the duration of their lifetimes.
|
||||
* @param[in] data_directory Non-null, path string of the directory containing the chainstate data.
|
||||
* If the directory does not exist yet, it will be created.
|
||||
* @param[in] blocks_directory Non-null, path string of the directory containing the block data. If
|
||||
* the directory does not exist yet, it will be created.
|
||||
* associate with this kernel context for the duration of their lifetimes.
|
||||
* @param[in] data_directory Non-null, non-empty path string of the directory containing the
|
||||
* chainstate data. If the directory does not exist yet, it will be
|
||||
* created.
|
||||
* @param[in] blocks_directory Non-null, non-empty path string of the directory containing the block
|
||||
* data. If the directory does not exist yet, it will be created.
|
||||
* @return The allocated chainstate manager options, or null on error.
|
||||
*/
|
||||
BITCOINKERNEL_API btck_ChainstateManagerOptions* BITCOINKERNEL_WARN_UNUSED_RESULT btck_chainstate_manager_options_create(
|
||||
@ -945,7 +957,7 @@ BITCOINKERNEL_API btck_ChainstateManagerOptions* BITCOINKERNEL_WARN_UNUSED_RESUL
|
||||
const char* data_directory,
|
||||
size_t data_directory_len,
|
||||
const char* blocks_directory,
|
||||
size_t blocks_directory_len) BITCOINKERNEL_ARG_NONNULL(1, 2);
|
||||
size_t blocks_directory_len) BITCOINKERNEL_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @brief Set the number of available worker threads used during validation.
|
||||
|
||||
@ -937,8 +937,9 @@ public:
|
||||
class ChainstateManagerOptions : public UniqueHandle<btck_ChainstateManagerOptions, btck_chainstate_manager_options_destroy>
|
||||
{
|
||||
public:
|
||||
ChainstateManagerOptions(const Context& context, const std::string& data_dir, const std::string& blocks_dir)
|
||||
: UniqueHandle{btck_chainstate_manager_options_create(context.get(), data_dir.c_str(), data_dir.length(), blocks_dir.c_str(), blocks_dir.length())}
|
||||
ChainstateManagerOptions(const Context& context, std::string_view data_dir, std::string_view blocks_dir)
|
||||
: UniqueHandle{btck_chainstate_manager_options_create(
|
||||
context.get(), data_dir.data(), data_dir.length(), blocks_dir.data(), blocks_dir.length())}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -625,6 +625,20 @@ BOOST_AUTO_TEST_CASE(btck_chainman_tests)
|
||||
ChainstateManagerOptions chainman_opts{context, test_directory.m_directory.string(), (test_directory.m_directory / "blocks").string()};
|
||||
ChainMan chainman{context, chainman_opts};
|
||||
}
|
||||
{ // null or empty data_directory or blocks_directory are not allowed
|
||||
Context context{};
|
||||
auto valid_dir{test_directory.m_directory.string()};
|
||||
std::vector<std::pair<std::string_view, std::string_view>> illegal_cases{
|
||||
{"", valid_dir},
|
||||
{valid_dir, {nullptr, 0}},
|
||||
{"", ""},
|
||||
{{nullptr, 0}, {nullptr, 0}},
|
||||
};
|
||||
for (auto& [data_dir, blocks_dir] : illegal_cases) {
|
||||
BOOST_CHECK_THROW(ChainstateManagerOptions(context, data_dir, blocks_dir),
|
||||
std::runtime_error);
|
||||
};
|
||||
}
|
||||
|
||||
auto notifications{std::make_shared<TestKernelNotifications>()};
|
||||
auto context{create_context(notifications, ChainType::MAINNET)};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user