IBD/sync speedups: parallel RandomX pre-verify, adaptive dbcache, P2P download fixes
- Parallel RandomX PoW pre-verification pool (CCheckQueue) run ahead of the serial connect; consensus-neutral (inline CheckRandomXSolution fallback still verifies anything not pre-verified). New -randomxverifythreads (default = -par). - Adaptive dbcache: default sizes the UTXO/coins cache to most of RAM and shrinks under memory pressure, always leaving a reserve free; -dbcache pins a fixed value. - P2P block download: bounded socket recv-drain loop (tlsmanager); frontier-block reassignment to break head-of-line stalls (-blockreassigntimeout); ProcessGetData serves a bounded batch of blocks per pass instead of one (fixes the serve-side one-block-per-tick throttle that caps download network-wide). - assumeutxo: dumptxoutset RPC + LoadSnapshot machinery + AssumeutxoData chainparams. - Signed bootstrap verification (util/bootstrap-dragonx.sh, util/sign-bootstrap.md). - gtest: RandomX pre-verify consensus-equivalence test + UTXO-snapshot round-trip; revived the gtest harness (Makefile.am include fix, Makefile.gtest.include). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
src/txdb.h
71
src/txdb.h
@@ -56,6 +56,61 @@ 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
|
||||
{
|
||||
@@ -81,6 +136,19 @@ 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/) */
|
||||
@@ -117,6 +185,9 @@ 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);
|
||||
|
||||
Reference in New Issue
Block a user