@@ -2683,6 +2683,23 @@ class NetworkDisable
2683
2683
};
2684
2684
};
2685
2685
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
+
2686
2703
/* *
2687
2704
* Serialize the UTXO set to a file for loading elsewhere.
2688
2705
*
@@ -2770,6 +2787,7 @@ static RPCHelpMan dumptxoutset()
2770
2787
CConnman& connman = EnsureConnman (node);
2771
2788
const CBlockIndex* invalidate_index{nullptr };
2772
2789
std::unique_ptr<NetworkDisable> disable_network;
2790
+ std::unique_ptr<TemporaryRollback> temporary_rollback;
2773
2791
2774
2792
// If the user wants to dump the txoutset of the current tip, we don't have
2775
2793
// to roll back at all
@@ -2798,7 +2816,7 @@ static RPCHelpMan dumptxoutset()
2798
2816
}
2799
2817
2800
2818
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);
2802
2820
}
2803
2821
2804
2822
Chainstate* chainstate;
@@ -2822,23 +2840,15 @@ static RPCHelpMan dumptxoutset()
2822
2840
// sister block of invalidate_index. This block (or a descendant) would
2823
2841
// be activated as the new tip and we would not get to new_tip_index.
2824
2842
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." );
2827
2845
} else {
2828
2846
std::tie (cursor, stats, tip) = PrepareUTXOSnapshot (*chainstate, node.rpc_interruption_point );
2829
2847
}
2830
2848
}
2831
2849
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);
2842
2852
2843
2853
result.pushKV (" path" , path.utf8string ());
2844
2854
return result;
0 commit comments