Skip to content

Commit

Permalink
rpc: Manage dumptxoutset rollback with RAII class
Browse files Browse the repository at this point in the history
  • Loading branch information
fjahr committed Sep 4, 2024
1 parent c5eaae3 commit 769dc84
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2683,6 +2683,23 @@ class NetworkDisable
};
};

/**
* RAII class that temporarily rolls back the local chain in it's constructor
* and rolls it forward again in it's destructor.
*/
class TemporaryRollback
{
ChainstateManager& m_chainman;
const CBlockIndex* m_invalidate_index;
public:
TemporaryRollback(ChainstateManager& chainman, const CBlockIndex* index) : m_chainman(chainman), m_invalidate_index(index) {
InvalidateBlock(m_chainman, m_invalidate_index->GetBlockHash());
};
~TemporaryRollback() {
ReconsiderBlock(m_chainman, m_invalidate_index->GetBlockHash());
};
};

/**
* Serialize the UTXO set to a file for loading elsewhere.
*
Expand Down Expand Up @@ -2770,6 +2787,7 @@ static RPCHelpMan dumptxoutset()
CConnman& connman = EnsureConnman(node);
const CBlockIndex* invalidate_index{nullptr};
std::unique_ptr<NetworkDisable> disable_network;
std::unique_ptr<TemporaryRollback> temporary_rollback;

// If the user wants to dump the txoutset of the current tip, we don't have
// to roll back at all
Expand Down Expand Up @@ -2798,7 +2816,7 @@ static RPCHelpMan dumptxoutset()
}

invalidate_index = WITH_LOCK(::cs_main, return node.chainman->ActiveChain().Next(target_index));
InvalidateBlock(*node.chainman, invalidate_index->GetBlockHash());
temporary_rollback = std::make_unique<TemporaryRollback>(*node.chainman, invalidate_index);
}

Chainstate* chainstate;
Expand All @@ -2823,22 +2841,14 @@ static RPCHelpMan dumptxoutset()
// be activated as the new tip and we would not get to new_tip_index.
if (target_index != chainstate->m_chain.Tip()) {
LogInfo("Failed to roll back to requested height, reverting to tip.\n");
error = JSONRPCError(RPC_MISC_ERROR, "Could not roll back to requested height.");
throw JSONRPCError(RPC_MISC_ERROR, "Could not roll back to requested height.");
} else {
std::tie(cursor, stats, tip) = PrepareUTXOSnapshot(*chainstate, node.rpc_interruption_point);
}
}

if (error.isNull()) {
result = WriteUTXOSnapshot(*chainstate, cursor.get(), &stats, tip, afile, path, temppath, node.rpc_interruption_point);
fs::rename(temppath, path);
}
if (invalidate_index) {
ReconsiderBlock(*node.chainman, invalidate_index->GetBlockHash());
}
if (!error.isNull()) {
throw error;
}
result = WriteUTXOSnapshot(*chainstate, cursor.get(), &stats, tip, afile, path, temppath, node.rpc_interruption_point);
fs::rename(temppath, path);

result.pushKV("path", path.utf8string());
return result;
Expand Down

0 comments on commit 769dc84

Please sign in to comment.