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:
2026-06-30 16:27:34 -05:00
parent 1f2b109d95
commit 84aefb5475
9 changed files with 2 additions and 703 deletions

View File

@@ -56,61 +56,6 @@ static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024;
//! min. -dbcache in (MiB)
static const int64_t nMinDbCache = 4;
/** Magic + version for the trusted UTXO-snapshot (assumeutxo-style) file format. */
static const uint32_t UTXO_SNAPSHOT_MAGIC = 0x58535844; // 'DXSX'
static const uint8_t UTXO_SNAPSHOT_VERSION = 1;
/**
* Header of a trusted chainstate snapshot taken at a final height H. On this private
* chain the chainstate is more than transparent UTXOs, so the snapshot also carries the
* Sapling commitment trees, the nullifier set, the best Sapling anchor and the pool value.
*
* File layout: [CUTXOSnapshotHeader]
* nCoins × (uint256 txid, CCoins)
* nSaplingAnchors × (uint256 root, SaplingMerkleTree)
* nSaplingNullifiers × (uint256 nullifier)
* uint256 contentHash // hash over everything above (NOT itself)
*/
struct CUTXOSnapshotHeader
{
uint32_t nMagic;
uint8_t nVersion;
uint32_t nNetworkMagic; // Params().MessageStart() as uint32 — prevents cross-network use
uint256 baseBlockHash; // hash of block H (the snapshot tip)
int32_t nHeight; // H
uint64_t nChainTx; // cumulative tx count at H (needed for tip fix-up)
uint8_t fHasChainSaplingValue;
int64_t nChainSaplingValue; // cumulative Sapling pool value at H (valid iff fHasChainSaplingValue)
uint256 bestSaplingAnchor; // best Sapling anchor root at H
uint64_t nCoins;
uint64_t nSaplingAnchors;
uint64_t nSaplingNullifiers;
CUTXOSnapshotHeader() { SetNull(); }
void SetNull() {
nMagic = 0; nVersion = 0; nNetworkMagic = 0; baseBlockHash.SetNull();
nHeight = 0; nChainTx = 0; fHasChainSaplingValue = 0; nChainSaplingValue = 0;
bestSaplingAnchor.SetNull(); nCoins = 0; nSaplingAnchors = 0; nSaplingNullifiers = 0;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(nMagic);
READWRITE(nVersion);
READWRITE(nNetworkMagic);
READWRITE(baseBlockHash);
READWRITE(nHeight);
READWRITE(nChainTx);
READWRITE(fHasChainSaplingValue);
READWRITE(nChainSaplingValue);
READWRITE(bestSaplingAnchor);
READWRITE(nCoins);
READWRITE(nSaplingAnchors);
READWRITE(nSaplingNullifiers);
}
};
/** CCoinsView backed by the coin database (chainstate/) */
class CCoinsViewDB : public CCoinsView
{
@@ -136,19 +81,6 @@ public:
CNullifiersMap &mapSproutNullifiers,
CNullifiersMap &mapSaplingNullifiers);
bool GetStats(CCoinsStats &stats) const;
//! Stream the full chainstate at the current tip into a snapshot file (assumeutxo-style
//! producer). Caller fills the metadata fields of `header` (height, baseBlockHash, nChainTx,
//! pool value, bestSaplingAnchor); this fills the counts, writes the file, and returns the
//! content hash. Caller must hold cs_main and have flushed the cache to disk first.
bool DumpSnapshot(const std::string &path, CUTXOSnapshotHeader &header, uint256 &hashRet, std::string &strError) const;
//! Load a snapshot file produced by DumpSnapshot into the (empty) chainstate DB. Two passes:
//! pass 1 reads everything and verifies the internal content hash (and, if fRequireExpected,
//! that it equals expectedHash) WITHOUT touching the DB; pass 2 writes coins/anchors/nullifiers
//! plus the best-block / best-sapling-anchor pointers. Returns the header + computed hash.
bool LoadSnapshot(const std::string &path, const uint256 &expectedHash, bool fRequireExpected,
CUTXOSnapshotHeader &headerRet, uint256 &hashRet, std::string &strError);
};
/** Access to the block database (blocks/index/) */
@@ -185,9 +117,6 @@ public:
bool ReadTimestampBlockIndex(const uint256 &hash, unsigned int &logicalTS) const;
bool WriteFlag(const std::string &name, bool fValue);
bool ReadFlag(const std::string &name, bool &fValue) const;
//! Persist/restore the height of a loaded UTXO snapshot so the reorg-below-H guard survives restarts.
bool WriteAssumeutxoHeight(int nHeight);
bool ReadAssumeutxoHeight(int &nHeight) const;
bool LoadBlockIndexGuts();
bool blockOnchainActive(const uint256 &hash);
UniValue Snapshot(int top);