77#include < kernel/bitcoinkernel.h>
88
99#include < consensus/amount.h>
10+ #include < consensus/validation.h>
1011#include < kernel/caches.h>
1112#include < kernel/chainparams.h>
1213#include < kernel/checks.h>
1617#include < kernel/warning.h>
1718#include < logging.h>
1819#include < node/blockstorage.h>
20+ #include < node/chainstate.h>
1921#include < primitives/transaction.h>
2022#include < script/interpreter.h>
2123#include < script/script.h>
3840#include < memory>
3941#include < span>
4042#include < string>
43+ #include < tuple>
4144#include < utility>
4245#include < vector>
4346
@@ -363,6 +366,7 @@ struct ChainstateManagerOptions {
363366 ChainstateManager::Options m_chainman_options GUARDED_BY (m_mutex);
364367 node::BlockManager::Options m_blockman_options GUARDED_BY (m_mutex);
365368 std::shared_ptr<const Context> m_context;
369+ node::ChainstateLoadOptions m_chainstate_load_options GUARDED_BY (m_mutex);
366370
367371 ChainstateManagerOptions (const std::shared_ptr<const Context>& context, const fs::path& data_dir, const fs::path& blocks_dir)
368372 : m_chainman_options{ChainstateManager::Options{
@@ -377,7 +381,7 @@ struct ChainstateManagerOptions {
377381 .path = data_dir / " blocks" / " index" ,
378382 .cache_bytes = kernel::CacheSizes{DEFAULT_KERNEL_CACHE}.block_tree_db ,
379383 }}},
380- m_context{context}
384+ m_context{context}, m_chainstate_load_options{node::ChainstateLoadOptions{}}
381385 {
382386 }
383387};
@@ -703,16 +707,44 @@ void btck_chainstate_manager_options_destroy(btck_ChainstateManagerOptions* opti
703707btck_ChainstateManager* btck_chainstate_manager_create (
704708 const btck_ChainstateManagerOptions* chainman_opts)
705709{
710+ auto & opts{btck_ChainstateManagerOptions::get (chainman_opts)};
711+ std::unique_ptr<ChainstateManager> chainman;
706712 try {
707- auto & opts{btck_ChainstateManagerOptions::get (chainman_opts)};
708713 LOCK (opts.m_mutex );
709- auto & context{opts.m_context };
710- auto chainman{std::make_unique<ChainstateManager>(*context->m_interrupt , opts.m_chainman_options , opts.m_blockman_options )};
711- return btck_ChainstateManager::create (std::move (chainman), context);
714+ chainman = std::make_unique<ChainstateManager>(*opts.m_context ->m_interrupt , opts.m_chainman_options , opts.m_blockman_options );
712715 } catch (const std::exception& e) {
713716 LogError (" Failed to create chainstate manager: %s" , e.what ());
714717 return nullptr ;
715718 }
719+
720+ try {
721+ const auto chainstate_load_opts{WITH_LOCK (opts.m_mutex , return opts.m_chainstate_load_options )};
722+
723+ kernel::CacheSizes cache_sizes{DEFAULT_KERNEL_CACHE};
724+ auto [status, chainstate_err]{node::LoadChainstate (*chainman, cache_sizes, chainstate_load_opts)};
725+ if (status != node::ChainstateLoadStatus::SUCCESS) {
726+ LogError (" Failed to load chain state from your data directory: %s" , chainstate_err.original );
727+ return nullptr ;
728+ }
729+ std::tie (status, chainstate_err) = node::VerifyLoadedChainstate (*chainman, chainstate_load_opts);
730+ if (status != node::ChainstateLoadStatus::SUCCESS) {
731+ LogError (" Failed to verify loaded chain state from your datadir: %s" , chainstate_err.original );
732+ return nullptr ;
733+ }
734+
735+ for (Chainstate* chainstate : WITH_LOCK (chainman->GetMutex (), return chainman->GetAll ())) {
736+ BlockValidationState state;
737+ if (!chainstate->ActivateBestChain (state, nullptr )) {
738+ LogError (" Failed to connect best block: %s" , state.ToString ());
739+ return nullptr ;
740+ }
741+ }
742+ } catch (const std::exception& e) {
743+ LogError (" Failed to load chainstate: %s" , e.what ());
744+ return nullptr ;
745+ }
746+
747+ return btck_ChainstateManager::create (std::move (chainman), opts.m_context );
716748}
717749
718750void btck_chainstate_manager_destroy (btck_ChainstateManager* chainman)
0 commit comments