Skip to content

Commit a3108a7

Browse files
committed
rpc: Manage dumptxoutset rollback with RAII class
1 parent c5eaae3 commit a3108a7

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

src/rpc/blockchain.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)