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)