From 1976b13be9c87baa1229b1573bdc8a1da562db0d Mon Sep 17 00:00:00 2001 From: TheCharlatan Date: Thu, 30 May 2024 11:22:28 +0200 Subject: [PATCH] kernel: Add import blocks function to C header Add `btck_import_blocks` to import block data and rebuild indexes. The function can either reindex all existing block files if the indexes were previously wiped through the chainstate manager options, or import blocks from specified file paths. --- src/kernel/bitcoinkernel.cpp | 18 ++++++++++++++++++ src/kernel/bitcoinkernel.h | 20 +++++++++++++++++++- src/kernel/bitcoinkernel_wrapper.h | 14 ++++++++++++++ src/test/kernel/test_kernel.cpp | 7 +++++++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp index 5203221d747..0c5d811db08 100644 --- a/src/kernel/bitcoinkernel.cpp +++ b/src/kernel/bitcoinkernel.cpp @@ -795,6 +795,24 @@ void btck_chainstate_manager_destroy(btck_ChainstateManager* chainman) delete chainman; } +int btck_chainstate_manager_import_blocks(btck_ChainstateManager* chainman, const char** block_file_paths_data, size_t* block_file_paths_lens, size_t block_file_paths_data_len) +{ + try { + std::vector import_files; + import_files.reserve(block_file_paths_data_len); + for (uint32_t i = 0; i < block_file_paths_data_len; i++) { + if (block_file_paths_data[i] != nullptr) { + import_files.emplace_back(std::string{block_file_paths_data[i], block_file_paths_lens[i]}.c_str()); + } + } + node::ImportBlocks(*btck_ChainstateManager::get(chainman).m_chainman, import_files); + } catch (const std::exception& e) { + LogError("Failed to import blocks: %s", e.what()); + return -1; + } + return 0; +} + btck_Block* btck_block_create(const void* raw_block, size_t raw_block_length) { auto block{std::make_shared()}; diff --git a/src/kernel/bitcoinkernel.h b/src/kernel/bitcoinkernel.h index c7c51ae4d6b..651c54c48f1 100644 --- a/src/kernel/bitcoinkernel.h +++ b/src/kernel/bitcoinkernel.h @@ -747,7 +747,9 @@ BITCOINKERNEL_API void btck_chainstate_manager_options_set_worker_threads_num( int worker_threads) BITCOINKERNEL_ARG_NONNULL(1); /** - * @brief Sets wipe db in the options. + * @brief Sets wipe db in the options. In combination with calling + * @ref btck_chainstate_manager_import_blocks this triggers either a full reindex, + * or a reindex of just the chainstate database. * * @param[in] chainstate_manager_options Non-null, created by @ref btck_chainstate_manager_options_create. * @param[in] wipe_block_tree_db Set wipe block tree db. Should only be 1 if wipe_chainstate_db is 1 too. @@ -802,6 +804,22 @@ BITCOINKERNEL_API void btck_chainstate_manager_options_destroy(btck_ChainstateMa BITCOINKERNEL_API btck_ChainstateManager* BITCOINKERNEL_WARN_UNUSED_RESULT btck_chainstate_manager_create( const btck_ChainstateManagerOptions* chainstate_manager_options) BITCOINKERNEL_ARG_NONNULL(1); +/** + * @brief Triggers the start of a reindex if the wipe options were previously + * set for the chainstate manager. Can also import an array of existing block + * files selected by the user. + * + * @param[in] chainstate_manager Non-null. + * @param[in] block_file_paths_data Nullable, array of block files described by their full filesystem paths. + * @param[in] block_file_paths_lens Nullable, array containing the lengths of each of the paths. + * @param[in] block_file_paths_data_len Length of the block_file_paths_data and block_file_paths_len arrays. + * @return 0 if the import blocks call was completed successfully, non-zero otherwise. + */ +BITCOINKERNEL_API int BITCOINKERNEL_WARN_UNUSED_RESULT btck_chainstate_manager_import_blocks( + btck_ChainstateManager* chainstate_manager, + const char** block_file_paths_data, size_t* block_file_paths_lens, + size_t block_file_paths_data_len) BITCOINKERNEL_ARG_NONNULL(1); + /** * @brief Process and validate the passed in block with the chainstate * manager. Processing first does checks on the block, and if these passed, diff --git a/src/kernel/bitcoinkernel_wrapper.h b/src/kernel/bitcoinkernel_wrapper.h index c3b3e6905ee..ff16f5bc042 100644 --- a/src/kernel/bitcoinkernel_wrapper.h +++ b/src/kernel/bitcoinkernel_wrapper.h @@ -690,6 +690,20 @@ public: { } + bool ImportBlocks(const std::span paths) + { + std::vector c_paths; + std::vector c_paths_lens; + c_paths.reserve(paths.size()); + c_paths_lens.reserve(paths.size()); + for (const auto& path : paths) { + c_paths.push_back(path.c_str()); + c_paths_lens.push_back(path.length()); + } + + return btck_chainstate_manager_import_blocks(get(), c_paths.data(), c_paths_lens.data(), c_paths.size()) == 0; + } + bool ProcessBlock(const Block& block, bool* new_block) { int _new_block; diff --git a/src/test/kernel/test_kernel.cpp b/src/test/kernel/test_kernel.cpp index 553d68f502a..128f3f49fb5 100644 --- a/src/test/kernel/test_kernel.cpp +++ b/src/test/kernel/test_kernel.cpp @@ -552,6 +552,9 @@ void chainman_reindex_test(TestDirectory& test_directory) auto notifications{std::make_shared()}; auto context{create_context(notifications, ChainType::MAINNET)}; auto chainman{create_chainman(test_directory, true, false, false, false, context)}; + + std::vector import_files; + BOOST_CHECK(chainman->ImportBlocks(import_files)); } void chainman_reindex_chainstate_test(TestDirectory& test_directory) @@ -559,6 +562,10 @@ void chainman_reindex_chainstate_test(TestDirectory& test_directory) auto notifications{std::make_shared()}; auto context{create_context(notifications, ChainType::MAINNET)}; auto chainman{create_chainman(test_directory, false, true, false, false, context)}; + + std::vector import_files; + import_files.push_back((test_directory.m_directory / "blocks" / "blk00000.dat").string()); + BOOST_CHECK(chainman->ImportBlocks(import_files)); } void chainman_mainnet_validation_test(TestDirectory& test_directory)