@@ -2683,6 +2683,23 @@ class NetworkDisable
26832683 };
26842684};
26852685
2686+ /* *
2687+ * RAII class that temporarily rolls back the local chain in it's constructor
2688+ * and rolls it forward again in it's destructor.
2689+ */
2690+ class TemporaryRollback
2691+ {
2692+ ChainstateManager& m_chainman;
2693+ const CBlockIndex& m_invalidate_index;
2694+ public:
2695+ TemporaryRollback (ChainstateManager& chainman, const CBlockIndex& index) : m_chainman(chainman), m_invalidate_index(index) {
2696+ InvalidateBlock (m_chainman, m_invalidate_index.GetBlockHash ());
2697+ };
2698+ ~TemporaryRollback () {
2699+ ReconsiderBlock (m_chainman, m_invalidate_index.GetBlockHash ());
2700+ };
2701+ };
2702+
26862703/* *
26872704 * Serialize the UTXO set to a file for loading elsewhere.
26882705 *
@@ -2770,6 +2787,7 @@ static RPCHelpMan dumptxoutset()
27702787 CConnman& connman = EnsureConnman (node);
27712788 const CBlockIndex* invalidate_index{nullptr };
27722789 std::unique_ptr<NetworkDisable> disable_network;
2790+ std::unique_ptr<TemporaryRollback> temporary_rollback;
27732791
27742792 // If the user wants to dump the txoutset of the current tip, we don't have
27752793 // to roll back at all
@@ -2798,7 +2816,7 @@ static RPCHelpMan dumptxoutset()
27982816 }
27992817
28002818 invalidate_index = WITH_LOCK (::cs_main, return node.chainman ->ActiveChain ().Next (target_index));
2801- InvalidateBlock (*node.chainman , invalidate_index-> GetBlockHash () );
2819+ temporary_rollback = std::make_unique<TemporaryRollback> (*node.chainman , * invalidate_index);
28022820 }
28032821
28042822 Chainstate* chainstate;
@@ -2822,23 +2840,15 @@ static RPCHelpMan dumptxoutset()
28222840 // sister block of invalidate_index. This block (or a descendant) would
28232841 // be activated as the new tip and we would not get to new_tip_index.
28242842 if (target_index != chainstate->m_chain .Tip ()) {
2825- LogInfo ( " Failed to roll back to requested height, reverting to tip.\n " );
2826- error = JSONRPCError (RPC_MISC_ERROR, " Could not roll back to requested height." );
2843+ LogWarning ( " dumptxoutset failed to roll back to requested height, reverting to tip.\n " );
2844+ throw JSONRPCError (RPC_MISC_ERROR, " Could not roll back to requested height." );
28272845 } else {
28282846 std::tie (cursor, stats, tip) = PrepareUTXOSnapshot (*chainstate, node.rpc_interruption_point );
28292847 }
28302848 }
28312849
2832- if (error.isNull ()) {
2833- result = WriteUTXOSnapshot (*chainstate, cursor.get (), &stats, tip, afile, path, temppath, node.rpc_interruption_point );
2834- fs::rename (temppath, path);
2835- }
2836- if (invalidate_index) {
2837- ReconsiderBlock (*node.chainman , invalidate_index->GetBlockHash ());
2838- }
2839- if (!error.isNull ()) {
2840- throw error;
2841- }
2850+ result = WriteUTXOSnapshot (*chainstate, cursor.get (), &stats, tip, afile, path, temppath, node.rpc_interruption_point );
2851+ fs::rename (temppath, path);
28422852
28432853 result.pushKV (" path" , path.utf8string ());
28442854 return result;
0 commit comments