Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpc: various fixups for dumptxoutset #23155

Merged
merged 1 commit into from
Dec 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
#include <core_io.h>
#include <deploymentinfo.h>
#include <deploymentstatus.h>
#include <fs.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
#include <node/blockstorage.h>
#include <logging/timer.h>
#include <node/coinstats.h>
#include <node/context.h>
#include <node/utxo_snapshot.h>
Expand Down Expand Up @@ -2547,6 +2549,8 @@ static RPCHelpMan dumptxoutset()
{RPCResult::Type::STR_HEX, "base_hash", "the hash of the base of the snapshot"},
{RPCResult::Type::NUM, "base_height", "the height of the base of the snapshot"},
{RPCResult::Type::STR, "path", "the absolute path that the snapshot was written to"},
{RPCResult::Type::STR_HEX, "txoutset_hash", "the hash of the UTXO set contents"},
{RPCResult::Type::NUM, "nchaintx", "the number of transactions in the chain up to and including the base block"},
}
},
RPCExamples{
Expand All @@ -2569,7 +2573,8 @@ static RPCHelpMan dumptxoutset()
FILE* file{fsbridge::fopen(temppath, "wb")};
CAutoFile afile{file, SER_DISK, CLIENT_VERSION};
NodeContext& node = EnsureAnyNodeContext(request.context);
UniValue result = CreateUTXOSnapshot(node, node.chainman->ActiveChainstate(), afile);
UniValue result = CreateUTXOSnapshot(
node, node.chainman->ActiveChainstate(), afile, path, temppath);
fs::rename(temppath, path);

result.pushKV("path", path.u8string());
Expand All @@ -2578,10 +2583,15 @@ static RPCHelpMan dumptxoutset()
};
}

UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFile& afile)
UniValue CreateUTXOSnapshot(
NodeContext& node,
CChainState& chainstate,
CAutoFile& afile,
const fs::path& path,
const fs::path& temppath)
{
std::unique_ptr<CCoinsViewCursor> pcursor;
CCoinsStats stats{CoinStatsHashType::NONE};
CCoinsStats stats{CoinStatsHashType::HASH_SERIALIZED};
CBlockIndex* tip;

{
Expand Down Expand Up @@ -2610,6 +2620,10 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
CHECK_NONFATAL(tip);
}

LOG_TIME_SECONDS(strprintf("writing UTXO snapshot at height %s (%s) to file %s (via %s)",
tip->nHeight, tip->GetBlockHash().ToString(),
fs::PathToString(path), fs::PathToString(temppath)));

SnapshotMetadata metadata{tip->GetBlockHash(), stats.coins_count, tip->nChainTx};

afile << metadata;
Expand All @@ -2635,7 +2649,11 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
result.pushKV("coins_written", stats.coins_count);
result.pushKV("base_hash", tip->GetBlockHash().ToString());
result.pushKV("base_height", tip->nHeight);

result.pushKV("path", path.u8string());
result.pushKV("txoutset_hash", stats.hashSerialized.ToString());
// Cast required because univalue doesn't have serialization specified for
// `unsigned int`, nChainTx's type.
result.pushKV("nchaintx", uint64_t{tip->nChainTx});
return result;
}

Expand Down
8 changes: 7 additions & 1 deletion src/rpc/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <consensus/amount.h>
#include <core_io.h>
#include <fs.h>
#include <streams.h>
#include <sync.h>

Expand Down Expand Up @@ -65,6 +66,11 @@ CBlockPolicyEstimator& EnsureAnyFeeEstimator(const std::any& context);
* Helper to create UTXO snapshots given a chainstate and a file handle.
* @return a UniValue map containing metadata about the snapshot.
*/
UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFile& afile);
UniValue CreateUTXOSnapshot(
NodeContext& node,
CChainState& chainstate,
CAutoFile& afile,
const fs::path& path,
const fs::path& tmppath);

#endif
3 changes: 2 additions & 1 deletion src/test/util/chainstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ CreateAndActivateUTXOSnapshot(NodeContext& node, const fs::path root, F malleati
FILE* outfile{fsbridge::fopen(snapshot_path, "wb")};
CAutoFile auto_outfile{outfile, SER_DISK, CLIENT_VERSION};

UniValue result = CreateUTXOSnapshot(node, node.chainman->ActiveChainstate(), auto_outfile);
UniValue result = CreateUTXOSnapshot(
node, node.chainman->ActiveChainstate(), auto_outfile, snapshot_path, snapshot_path);
BOOST_TEST_MESSAGE(
"Wrote UTXO snapshot to " << fs::PathToString(snapshot_path.make_preferred()) << ": " << result.write());

Expand Down
4 changes: 4 additions & 0 deletions test/functional/rpc_dumptxoutset.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def run_test(self):
assert_equal(
digest, '7ae82c986fa5445678d2a21453bb1c86d39e47af13da137640c2b1cf8093691c')

assert_equal(
out['txoutset_hash'], 'd4b614f476b99a6e569973bf1c0120d88b1a168076f8ce25691fb41dd1cef149')
assert_equal(out['nchaintx'], 101)

# Specifying a path to an existing file will fail.
assert_raises_rpc_error(
-8, '{} already exists'.format(FILENAME), node.dumptxoutset, FILENAME)
Expand Down