diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp index 972b9cc9441..c17ca372130 100644 --- a/src/kernel/bitcoinkernel.cpp +++ b/src/kernel/bitcoinkernel.cpp @@ -715,6 +715,24 @@ int btck_chainstate_manager_options_set_wipe_dbs(btck_ChainstateManagerOptions* return 0; } +void btck_chainstate_manager_options_set_block_tree_db_in_memory( + btck_ChainstateManagerOptions* chainman_opts, + int block_tree_db_in_memory) +{ + auto& opts{btck_ChainstateManagerOptions::get(chainman_opts)}; + LOCK(opts.m_mutex); + opts.m_blockman_options.block_tree_db_params.memory_only = block_tree_db_in_memory == 1; +} + +void btck_chainstate_manager_options_set_chainstate_db_in_memory( + btck_ChainstateManagerOptions* chainman_opts, + int chainstate_db_in_memory) +{ + auto& opts{btck_ChainstateManagerOptions::get(chainman_opts)}; + LOCK(opts.m_mutex); + opts.m_chainstate_load_options.coins_db_in_memory = chainstate_db_in_memory == 1; +} + btck_ChainstateManager* btck_chainstate_manager_create( const btck_ChainstateManagerOptions* chainman_opts) { diff --git a/src/kernel/bitcoinkernel.h b/src/kernel/bitcoinkernel.h index c871a4b5dfb..4c804a3a261 100644 --- a/src/kernel/bitcoinkernel.h +++ b/src/kernel/bitcoinkernel.h @@ -744,6 +744,26 @@ BITCOINKERNEL_API int btck_chainstate_manager_options_set_wipe_dbs( int wipe_block_tree_db, int wipe_chainstate_db) BITCOINKERNEL_ARG_NONNULL(1); +/** + * @brief Sets block tree db in memory in the options. + * + * @param[in] chainstate_manager_options Non-null, created by @ref btck_chainstate_manager_options_create. + * @param[in] block_tree_db_in_memory Set block tree db in memory. + */ +BITCOINKERNEL_API void btck_chainstate_manager_options_set_block_tree_db_in_memory( + btck_ChainstateManagerOptions* chainstate_manager_options, + int block_tree_db_in_memory) BITCOINKERNEL_ARG_NONNULL(1); + +/** + * @brief Sets chainstate db in memory in the options. + * + * @param[in] chainstate_manager_options Non-null, created by @ref btck_chainstate_manager_options_create. + * @param[in] chainstate_db_in_memory Set chainstate db in memory. + */ +BITCOINKERNEL_API void btck_chainstate_manager_options_set_chainstate_db_in_memory( + btck_ChainstateManagerOptions* chainstate_manager_options, + int chainstate_db_in_memory) BITCOINKERNEL_ARG_NONNULL(1); + /** * Destroy the chainstate manager options. */ diff --git a/src/kernel/bitcoinkernel_wrapper.h b/src/kernel/bitcoinkernel_wrapper.h index 248a286295a..e5925ffbffb 100644 --- a/src/kernel/bitcoinkernel_wrapper.h +++ b/src/kernel/bitcoinkernel_wrapper.h @@ -678,6 +678,16 @@ public: return btck_chainstate_manager_options_set_wipe_dbs(get(), wipe_block_tree, wipe_chainstate) == 0; } + void SetBlockTreeDbInMemory(bool block_tree_db_in_memory) + { + btck_chainstate_manager_options_set_block_tree_db_in_memory(get(), block_tree_db_in_memory); + } + + void SetChainstateDbInMemory(bool chainstate_db_in_memory) + { + btck_chainstate_manager_options_set_chainstate_db_in_memory(get(), chainstate_db_in_memory); + } + friend class ChainMan; }; diff --git a/src/test/kernel/test_kernel.cpp b/src/test/kernel/test_kernel.cpp index e5c0405210c..8f2e2af2ce0 100644 --- a/src/test/kernel/test_kernel.cpp +++ b/src/test/kernel/test_kernel.cpp @@ -539,6 +539,8 @@ BOOST_AUTO_TEST_CASE(btck_chainman_tests) std::unique_ptr create_chainman(TestDirectory& test_directory, bool reindex, bool wipe_chainstate, + bool block_tree_db_in_memory, + bool chainstate_db_in_memory, Context& context) { auto mainnet_test_directory{TestDirectory{"mainnet_test_bitcoin_kernel"}}; @@ -551,6 +553,12 @@ std::unique_ptr create_chainman(TestDirectory& test_directory, if (wipe_chainstate) { chainman_opts.SetWipeDbs(/*wipe_block_tree=*/false, /*wipe_chainstate=*/wipe_chainstate); } + if (block_tree_db_in_memory) { + chainman_opts.SetBlockTreeDbInMemory(block_tree_db_in_memory); + } + if (chainstate_db_in_memory) { + chainman_opts.SetChainstateDbInMemory(chainstate_db_in_memory); + } auto chainman{std::make_unique(context, chainman_opts)}; return chainman; @@ -571,21 +579,21 @@ 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, context)}; + auto chainman{create_chainman(test_directory, true, false, false, false, context)}; } 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, context)}; + auto chainman{create_chainman(test_directory, false, true, false, false, context)}; } void chainman_mainnet_validation_test(TestDirectory& test_directory) { auto notifications{std::make_shared()}; auto context{create_context(notifications, ChainType::MAINNET)}; - auto chainman{create_chainman(test_directory, false, false, context)}; + auto chainman{create_chainman(test_directory, false, false, false, false, context)}; { // Process an invalid block @@ -638,6 +646,25 @@ BOOST_AUTO_TEST_CASE(btck_chainman_mainnet_tests) chainman_reindex_chainstate_test(test_directory); } +BOOST_AUTO_TEST_CASE(btck_chainman_in_memory_tests) +{ + auto in_memory_test_directory{TestDirectory{"in-memory_test_bitcoin_kernel"}}; + + auto notifications{std::make_shared()}; + auto context{create_context(notifications, ChainType::REGTEST)}; + auto chainman{create_chainman(in_memory_test_directory, false, false, true, true, context)}; + + for (auto& raw_block : REGTEST_BLOCK_DATA) { + Block block{as_bytes(raw_block)}; + bool new_block{false}; + chainman->ProcessBlock(block, &new_block); + BOOST_CHECK(new_block); + } + + BOOST_CHECK(!std::filesystem::exists(in_memory_test_directory.m_directory / "blocks" / "index")); + BOOST_CHECK(!std::filesystem::exists(in_memory_test_directory.m_directory / "chainstate")); +} + BOOST_AUTO_TEST_CASE(btck_chainman_regtest_tests) { auto test_directory{TestDirectory{"regtest_test_bitcoin_kernel"}}; @@ -651,7 +678,7 @@ BOOST_AUTO_TEST_CASE(btck_chainman_regtest_tests) const size_t mid{REGTEST_BLOCK_DATA.size() / 2}; { - auto chainman{create_chainman(test_directory, false, false, context)}; + auto chainman{create_chainman(test_directory, false, false, false, false, context)}; for (size_t i{0}; i < mid; i++) { Block block{as_bytes(REGTEST_BLOCK_DATA[i])}; bool new_block{false}; @@ -660,7 +687,7 @@ BOOST_AUTO_TEST_CASE(btck_chainman_regtest_tests) } } - auto chainman{create_chainman(test_directory, false, false, context)}; + auto chainman{create_chainman(test_directory, false, false, false, false, context)}; for (size_t i{mid}; i < REGTEST_BLOCK_DATA.size(); i++) { Block block{as_bytes(REGTEST_BLOCK_DATA[i])};