diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp index c17ca372130..749bce886e6 100644 --- a/src/kernel/bitcoinkernel.cpp +++ b/src/kernel/bitcoinkernel.cpp @@ -791,6 +791,25 @@ 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); + btck_ChainstateManager::get(chainman).m_chainman->ActiveChainstate().ForceFlushStateToDisk(); + } 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 4c804a3a261..fca29831510 100644 --- a/src/kernel/bitcoinkernel.h +++ b/src/kernel/bitcoinkernel.h @@ -732,7 +732,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. @@ -787,6 +789,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 option was previously set for + * the chainstate and block 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 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, 2); + /** * @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 e5925ffbffb..b1c943fb2e0 100644 --- a/src/kernel/bitcoinkernel_wrapper.h +++ b/src/kernel/bitcoinkernel_wrapper.h @@ -699,6 +699,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 8f2e2af2ce0..894b94ebd9c 100644 --- a/src/test/kernel/test_kernel.cpp +++ b/src/test/kernel/test_kernel.cpp @@ -580,6 +580,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) @@ -587,6 +590,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)