diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 3ba89d08d9830..b94b3a64e1305 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -56,6 +56,7 @@ #include #include #include +#include using kernel::CCoinsStats; using kernel::CoinStatsHashType; @@ -2786,8 +2787,8 @@ static RPCHelpMan dumptxoutset() CConnman& connman = EnsureConnman(node); const CBlockIndex* invalidate_index{nullptr}; - std::unique_ptr disable_network; - std::unique_ptr temporary_rollback; + std::optional disable_network; + std::optional temporary_rollback; // If the user wants to dump the txoutset of the current tip, we don't have // to roll back at all @@ -2812,18 +2813,16 @@ static RPCHelpMan dumptxoutset() // automatically re-enables the network activity at the end of the // process which may not be what the user wants. if (connman.GetNetworkActive()) { - disable_network = std::make_unique(connman); + disable_network.emplace(connman); } invalidate_index = WITH_LOCK(::cs_main, return node.chainman->ActiveChain().Next(target_index)); - temporary_rollback = std::make_unique(*node.chainman, *invalidate_index); + temporary_rollback.emplace(*node.chainman, *invalidate_index); } Chainstate* chainstate; std::unique_ptr cursor; CCoinsStats stats; - UniValue result; - UniValue error; { // Lock the chainstate before calling PrepareUtxoSnapshot, to be able // to get a UTXO database cursor while the chain is pointing at the @@ -2847,7 +2846,7 @@ static RPCHelpMan dumptxoutset() } } - result = WriteUTXOSnapshot(*chainstate, cursor.get(), &stats, tip, afile, path, temppath, node.rpc_interruption_point); + UniValue result = WriteUTXOSnapshot(*chainstate, cursor.get(), &stats, tip, afile, path, temppath, node.rpc_interruption_point); fs::rename(temppath, path); result.pushKV("path", path.utf8string()); diff --git a/test/functional/rpc_dumptxoutset.py b/test/functional/rpc_dumptxoutset.py index 2542ddd220b91..3262c664add18 100755 --- a/test/functional/rpc_dumptxoutset.py +++ b/test/functional/rpc_dumptxoutset.py @@ -28,7 +28,7 @@ def run_test(self): FILENAME = 'txoutset.dat' out = node.dumptxoutset(FILENAME, "latest") - expected_path = node.datadir_path / self.chain / FILENAME + expected_path = node.chain_path / FILENAME assert expected_path.is_file() @@ -60,6 +60,16 @@ def run_test(self): assert_raises_rpc_error( -8, 'Invalid snapshot type "bogus" specified. Please specify "rollback" or "latest"', node.dumptxoutset, 'utxos.dat', "bogus") + self.log.info(f"Test that dumptxoutset failure does not leave the network activity suspended") + rev_file = node.blocks_path / "rev00000.dat" + bogus_file = node.blocks_path / "bogus.dat" + rev_file.rename(bogus_file) + assert_raises_rpc_error( + -1, 'Could not roll back to requested height.', node.dumptxoutset, 'utxos.dat', rollback=99) + assert_equal(node.getnetworkinfo()['networkactive'], True) + + # Cleanup + bogus_file.rename(rev_file) if __name__ == '__main__': DumptxoutsetTest(__file__).main()