Remove assumeutxo / UTXO-snapshot feature
Removes the dumptxoutset RPC, -loadutxosnapshot / -loadutxosnapshotunsafe, the CCoinsViewDB Dump/LoadSnapshot machinery + CUTXOSnapshotHeader, the AssumeutxoData chainparams anchor, the LoadSnapshotChainstate activation + reorg-below-H guard, the persisted assumeutxo-height flag, and the gtest. Rationale: it duplicated the existing bootstrap (same skip-the-genesis-grind fast-sync, no speed advantage), its only real edge was a trust model we don't need for this chain, and it was inert anyway (no published snapshot hash in chainparams). The -loadutxosnapshot load path adopted an external UTXO set and bypassed genesis validation, so removing it also drops that attack surface. Builds clean (no dangling references); the kept IBD speedups (RandomX pre-verify, adaptive dbcache, tlsmanager) are untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -862,76 +862,6 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp, const CPubKey& mypk
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue dumptxoutset(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
"dumptxoutset \"path\"\n"
|
||||
"\nWrite a trusted snapshot of the current chainstate (UTXO set + Sapling commitment\n"
|
||||
"trees, nullifier set and pool value) to disk. The snapshot can be loaded by a fresh\n"
|
||||
"node with -loadutxosnapshot=<file> to skip replaying the chain from genesis.\n"
|
||||
"\nThis is intended to be run at a final/checkpoint height; the node must be fully synced.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"path\" (string, required) path to write the snapshot file (must not already exist)\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"height\": n, (numeric) snapshot height H\n"
|
||||
" \"base_hash\": \"hex\", (string) block hash at height H\n"
|
||||
" \"snapshot_hash\": \"hex\", (string) content hash to hardcode for verification\n"
|
||||
" \"coins\": n, (numeric) number of UTXO records\n"
|
||||
" \"sapling_anchors\": n, (numeric) number of Sapling anchor records\n"
|
||||
" \"sapling_nullifiers\": n, (numeric) number of Sapling nullifier records\n"
|
||||
" \"path\": \"...\" (string) the file written\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("dumptxoutset", "/path/to/dragonx-utxo.dat")
|
||||
+ HelpExampleRpc("dumptxoutset", "\"/path/to/dragonx-utxo.dat\"")
|
||||
);
|
||||
|
||||
boost::filesystem::path path = boost::filesystem::absolute(params[0].get_str());
|
||||
if (boost::filesystem::exists(path))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "path already exists, refusing to overwrite: " + path.string());
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
if (pcoinsdbview == nullptr || pcoinsTip == nullptr)
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "chainstate not available");
|
||||
|
||||
// Flush so the on-disk chainstate matches the in-memory tip before we iterate it.
|
||||
FlushStateToDisk();
|
||||
|
||||
CBlockIndex *tip = chainActive.Tip();
|
||||
if (tip == nullptr)
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "no chain tip");
|
||||
|
||||
CUTXOSnapshotHeader header;
|
||||
header.nMagic = UTXO_SNAPSHOT_MAGIC;
|
||||
header.nVersion = UTXO_SNAPSHOT_VERSION;
|
||||
memcpy(&header.nNetworkMagic, Params().MessageStart(), 4);
|
||||
header.baseBlockHash = tip->GetBlockHash();
|
||||
header.nHeight = tip->GetHeight();
|
||||
header.nChainTx = tip->nChainTx;
|
||||
if (tip->nChainSaplingValue) {
|
||||
header.fHasChainSaplingValue = 1;
|
||||
header.nChainSaplingValue = *tip->nChainSaplingValue;
|
||||
}
|
||||
header.bestSaplingAnchor = pcoinsdbview->GetBestAnchor(SAPLING);
|
||||
|
||||
uint256 snapshotHash;
|
||||
std::string strError;
|
||||
if (!pcoinsdbview->DumpSnapshot(path.string(), header, snapshotHash, strError))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "dumptxoutset failed: " + strError);
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("height", (int64_t)header.nHeight));
|
||||
ret.push_back(Pair("base_hash", header.baseBlockHash.GetHex()));
|
||||
ret.push_back(Pair("snapshot_hash", snapshotHash.GetHex()));
|
||||
ret.push_back(Pair("coins", (int64_t)header.nCoins));
|
||||
ret.push_back(Pair("sapling_anchors", (int64_t)header.nSaplingAnchors));
|
||||
ret.push_back(Pair("sapling_nullifiers", (int64_t)header.nSaplingNullifiers));
|
||||
ret.push_back(Pair("path", path.string()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue getblockmerkletree(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
{
|
||||
@@ -1924,7 +1854,6 @@ static const CRPCCommand commands[] =
|
||||
{ "blockchain", "getrawmempool", &getrawmempool, true },
|
||||
{ "blockchain", "gettxout", &gettxout, true },
|
||||
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
|
||||
{ "blockchain", "dumptxoutset", &dumptxoutset, true },
|
||||
{ "blockchain", "verifychain", &verifychain, true },
|
||||
|
||||
/* Not shown in help */
|
||||
|
||||
Reference in New Issue
Block a user