2323#include < index/blockfilterindex.h>
2424#include < index/coinstatsindex.h>
2525#include < interfaces/mining.h>
26+ #include < interfaces/node.h>
27+ #include < interfaces/snapshot.h>
2628#include < kernel/coinstats.h>
2729#include < logging/timer.h>
2830#include < net.h>
@@ -67,6 +69,8 @@ using kernel::CoinStatsHashType;
6769
6870using interfaces::BlockRef;
6971using interfaces::Mining;
72+ using interfaces::Node;
73+ using interfaces::Snapshot;
7074using node::BlockManager;
7175using node::NodeContext;
7276using node::SnapshotMetadata;
@@ -3345,27 +3349,37 @@ static RPCHelpMan loadtxoutset()
33453349 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
33463350{
33473351 NodeContext& node = EnsureAnyNodeContext (request.context );
3348- ChainstateManager& chainman = EnsureChainman (node);
33493352 const fs::path path{AbsPathForConfigVal (EnsureArgsman (node), fs::u8path (self.Arg <std::string>(" path" )))};
3353+ auto node_interface = interfaces::MakeNode (node);
3354+ auto snapshot = node_interface->snapshot (path);
3355+ if (!snapshot) {
3356+ throw JSONRPCError (RPC_INTERNAL_ERROR, strprintf (" Unable to load UTXO snapshot: %s" , path.utf8string ()));
3357+ }
3358+ if (!snapshot->activate ()) {
3359+ std::string error_msg = snapshot->getLastError ();
3360+ if (error_msg.empty ()) {
3361+ error_msg = path.utf8string ();
3362+ }
3363+ if (error_msg.find (" Unable to parse metadata" ) != std::string::npos) {
3364+ throw JSONRPCError (RPC_DESERIALIZATION_ERROR, error_msg);
3365+ }
3366+ if (error_msg.find (" Snapshot file does not exist" ) != std::string::npos) {
3367+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Couldn't open file " + path.utf8string () + " for reading." );
3368+ }
33503369
3351- FILE* file{fsbridge::fopen (path, " rb" )};
3352- AutoFile afile{file};
3353- if (afile.IsNull ()) {
3354- throw JSONRPCError (
3355- RPC_INVALID_PARAMETER,
3356- " Couldn't open file " + path.utf8string () + " for reading." );
3370+ throw JSONRPCError (RPC_INTERNAL_ERROR, strprintf (" Unable to load UTXO snapshot: %s. (%s)" , error_msg, path.utf8string ()));
33573371 }
33583372
3359- SnapshotMetadata metadata{chainman. GetParams (). MessageStart ()} ;
3373+ const node:: SnapshotMetadata* metadata;
33603374 try {
3361- afile >> metadata ;
3375+ metadata = &snapshot-> getMetadata () ;
33623376 } catch (const std::ios_base::failure& e) {
33633377 throw JSONRPCError (RPC_DESERIALIZATION_ERROR, strprintf (" Unable to parse metadata: %s" , e.what ()));
33643378 }
33653379
3366- auto activation_result{chainman. ActivateSnapshot (afile, metadata, false )} ;
3380+ auto activation_result = snapshot-> getActivationResult () ;
33673381 if (!activation_result) {
3368- throw JSONRPCError (RPC_INTERNAL_ERROR, strprintf (" Unable to load UTXO snapshot: %s. (%s) " , util::ErrorString (activation_result). original , path.utf8string ()));
3382+ throw JSONRPCError (RPC_INTERNAL_ERROR, strprintf (" Unable to load UTXO snapshot: %s" , path.utf8string ()));
33693383 }
33703384
33713385 // Because we can't provide historical blocks during tip or background sync.
@@ -3375,10 +3389,10 @@ static RPCHelpMan loadtxoutset()
33753389 // provide the last 288 blocks, but it doesn't hurt to set it.
33763390 node.connman ->AddLocalServices (NODE_NETWORK_LIMITED);
33773391
3378- CBlockIndex& snapshot_index{*CHECK_NONFATAL (*activation_result)};
3392+ const CBlockIndex& snapshot_index{*CHECK_NONFATAL (*activation_result)};
33793393
33803394 UniValue result (UniValue::VOBJ);
3381- result.pushKV (" coins_loaded" , metadata. m_coins_count );
3395+ result.pushKV (" coins_loaded" , metadata-> m_coins_count );
33823396 result.pushKV (" tip_hash" , snapshot_index.GetBlockHash ().ToString ());
33833397 result.pushKV (" base_height" , snapshot_index.nHeight );
33843398 result.pushKV (" path" , fs::PathToString (path));
0 commit comments