From e66c2aea32f76f2403e82e3dffa1f44d69bb09c4 Mon Sep 17 00:00:00 2001 From: Anthony Fieroni Date: Mon, 8 Jun 2020 17:22:11 +0300 Subject: [PATCH 1/2] Add claims hash to node table Signed-off-by: Anthony Fieroni --- src/claimtrie/forks.cpp | 42 +++++++------- src/claimtrie/forks.h | 2 +- src/claimtrie/trie.cpp | 123 ++++++++++++++++++++++++++++------------ src/claimtrie/trie.h | 6 +- src/httpserver.cpp | 1 + src/validation.cpp | 10 ++-- 6 files changed, 123 insertions(+), 61 deletions(-) diff --git a/src/claimtrie/forks.cpp b/src/claimtrie/forks.cpp index 27654b145..4c1cbc202 100644 --- a/src/claimtrie/forks.cpp +++ b/src/claimtrie/forks.cpp @@ -139,10 +139,10 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary() // make the new nodes db << "INSERT INTO node(name) SELECT NORMALIZED(name) AS nn FROM claim WHERE nn != nodeName " - "AND activationHeight <= ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight; + "AND activationHeight <= ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL, claimsHash = NULL" << nNextHeight; // there's a subtlety here: names in supports don't make new nodes - db << "UPDATE node SET hash = NULL WHERE name IN " + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name IN " "(SELECT NORMALIZED(name) AS nn FROM support WHERE nn != nodeName " "AND activationHeight <= ?1 AND expirationHeight > ?1)" << nNextHeight; @@ -151,7 +151,7 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary() db << "UPDATE support SET nodeName = NORMALIZED(name) WHERE activationHeight <= ?1 AND expirationHeight > ?1" << nNextHeight; // remove the old nodes - db << "UPDATE node SET hash = NULL WHERE name NOT IN " + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name NOT IN " "(SELECT nodeName FROM claim WHERE activationHeight <= ?1 AND expirationHeight > ?1 " "UNION SELECT nodeName FROM support WHERE activationHeight <= ?1 AND expirationHeight > ?1)" << nNextHeight; @@ -167,9 +167,9 @@ bool CClaimTrieCacheNormalizationFork::unnormalizeAllNamesInTrieIfNecessary() ensureTransacting(); db << "INSERT INTO node(name) SELECT name FROM claim WHERE name != nodeName " - "AND activationHeight < ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight; + "AND activationHeight < ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL, claimsHash = NULL" << nNextHeight; - db << "UPDATE node SET hash = NULL WHERE name IN " + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name IN " "(SELECT nodeName FROM support WHERE name != nodeName " "UNION SELECT nodeName FROM claim WHERE name != nodeName)"; @@ -177,7 +177,7 @@ bool CClaimTrieCacheNormalizationFork::unnormalizeAllNamesInTrieIfNecessary() db << "UPDATE support SET nodeName = name"; // we need to let the tree structure method do the actual node delete - db << "UPDATE node SET hash = NULL WHERE name NOT IN " + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name NOT IN " "(SELECT DISTINCT name FROM claim)"; return true; @@ -242,10 +242,10 @@ uint256 ComputeMerkleRoot(std::vector hashes) return hashes.empty() ? uint256{} : hashes[0]; } -uint256 CClaimTrieCacheHashFork::computeNodeHash(const std::string& name, int takeoverHeight) +uint256 CClaimTrieCacheHashFork::computeNodeHash(const std::string& name, uint256& claimsHash, int takeoverHeight) { if (nNextHeight < base->nAllClaimsInMerkleForkHeight) - return CClaimTrieCacheNormalizationFork::computeNodeHash(name, takeoverHeight); + return CClaimTrieCacheNormalizationFork::computeNodeHash(name, claimsHash, takeoverHeight); std::vector childHashes; childHashQuery << name >> [&childHashes](std::string, uint256 hash) { @@ -253,20 +253,24 @@ uint256 CClaimTrieCacheHashFork::computeNodeHash(const std::string& name, int ta }; childHashQuery++; - std::vector claimHashes; if (takeoverHeight > 0) { - COutPoint p; - for (auto &&row: claimHashQuery << nNextHeight << name) { - row >> p.hash >> p.n; - claimHashes.push_back(getValueHash(p, takeoverHeight)); + if (claimsHash.IsNull()) { + COutPoint p; + std::vector hashes; + for (auto&& row: claimHashQuery << nNextHeight << name) { + row >> p.hash >> p.n; + hashes.push_back(getValueHash(p, takeoverHeight)); + } + claimHashQuery++; + claimsHash = hashes.empty() ? emptyHash : ComputeMerkleRoot(std::move(hashes)); } - claimHashQuery++; + } else { + claimsHash = emptyHash; } - auto left = childHashes.empty() ? leafHash : ComputeMerkleRoot(std::move(childHashes)); - auto right = claimHashes.empty() ? emptyHash : ComputeMerkleRoot(std::move(claimHashes)); + const auto& childrenHash = childHashes.empty() ? leafHash : ComputeMerkleRoot(std::move(childHashes)); - return Hash(left.begin(), left.end(), right.begin(), right.end()); + return Hash(childrenHash.begin(), childrenHash.end(), claimsHash.begin(), claimsHash.end()); } std::vector ComputeMerklePath(const std::vector& hashes, uint32_t idx) @@ -397,7 +401,7 @@ void CClaimTrieCacheHashFork::initializeIncrement() // we could do this in the constructor, but that would not allow for multiple increments in a row (as done in unit tests) if (nNextHeight == base->nAllClaimsInMerkleForkHeight - 1) { ensureTransacting(); - db << "UPDATE node SET hash = NULL"; + db << "UPDATE node SET hash = NULL, claimsHash = NULL"; } } @@ -406,7 +410,7 @@ bool CClaimTrieCacheHashFork::finalizeDecrement() auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement(); if (ret && nNextHeight == base->nAllClaimsInMerkleForkHeight - 1) { ensureTransacting(); - db << "UPDATE node SET hash = NULL"; + db << "UPDATE node SET hash = NULL, claimsHash = NULL"; } return ret; } diff --git a/src/claimtrie/forks.h b/src/claimtrie/forks.h index 0e780bcc7..c2b98550c 100644 --- a/src/claimtrie/forks.h +++ b/src/claimtrie/forks.h @@ -62,7 +62,7 @@ public: bool allowSupportMetadata() const; protected: - uint256 computeNodeHash(const std::string& name, int takeoverHeight) override; + uint256 computeNodeHash(const std::string& name, uint256& claimsHash, int takeoverHeight) override; }; typedef CClaimTrieCacheHashFork CClaimTrieCache; diff --git a/src/claimtrie/trie.cpp b/src/claimtrie/trie.cpp index c3b26e2bd..5b614b393 100644 --- a/src/claimtrie/trie.cpp +++ b/src/claimtrie/trie.cpp @@ -76,7 +76,7 @@ CClaimTrie::CClaimTrie(std::size_t cacheBytes, bool fWipe, int height, db << "CREATE TABLE IF NOT EXISTS node (name BLOB NOT NULL PRIMARY KEY, " "parent BLOB REFERENCES node(name) DEFERRABLE INITIALLY DEFERRED, " - "hash BLOB)"; + "hash BLOB, claimsHash BLOB)"; db << "CREATE TABLE IF NOT EXISTS claim (claimID BLOB NOT NULL PRIMARY KEY, name BLOB NOT NULL, " "nodeName BLOB NOT NULL REFERENCES node(name) DEFERRABLE INITIALLY DEFERRED, " @@ -99,6 +99,8 @@ CClaimTrie::CClaimTrie(std::size_t cacheBytes, bool fWipe, int height, db << "DELETE FROM takeover"; } + doNodeTableMigration(); + db << "CREATE INDEX IF NOT EXISTS node_hash_len_name ON node (hash, LENGTH(name) DESC)"; // db << "CREATE UNIQUE INDEX IF NOT EXISTS node_parent_name ON node (parent, name)"; // no apparent gain db << "CREATE INDEX IF NOT EXISTS node_parent ON node (parent)"; @@ -117,6 +119,29 @@ CClaimTrie::CClaimTrie(std::size_t cacheBytes, bool fWipe, int height, db << "INSERT OR IGNORE INTO node(name, hash) VALUES(x'', ?)" << one; // ensure that we always have our root node } +void CClaimTrie::doNodeTableMigration() +{ + try { + isNodeMigrationStart = false; + for (auto&& row : db << "SELECT claimsHash FROM node WHERE name = x''") + break; + } catch (const sqlite::sqlite_exception&) { + + isNodeMigrationStart = true; + + // new node schema + db << "CREATE TABLE node_new (name BLOB NOT NULL PRIMARY KEY, " + "parent BLOB REFERENCES node(name) DEFERRABLE INITIALLY DEFERRED, " + "hash BLOB, claimsHash BLOB)"; + + db << "INSERT OR REPLACE INTO node_new(name, parent, hash) " + "SELECT name, parent, hash FROM node"; + + db << "DROP TABLE node"; + db << "ALTER TABLE node_new RENAME TO node"; + } +} + CClaimTrieCacheBase::~CClaimTrieCacheBase() { if (transacting) { @@ -277,7 +302,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() "name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL " "SELECT POPS(p) FROM prefix WHERE p != x'') SELECT p FROM prefix)"; - auto insertQuery = db << "INSERT INTO node(name, parent, hash) VALUES(?, ?, NULL) " + auto insertQuery = db << "INSERT INTO node(name, parent, hash, claimsHash) VALUES(?, ?, NULL, NULL) " "ON CONFLICT(name) DO UPDATE SET parent = excluded.parent, hash = NULL"; auto nodeQuery = db << "SELECT name FROM node WHERE parent = ?"; @@ -436,7 +461,7 @@ void completeHash(uint256& partialHash, const std::string& key, int to) partialHash = Hash(it, it + 1, partialHash.begin(), partialHash.end()); } -uint256 CClaimTrieCacheBase::computeNodeHash(const std::string& name, int takeoverHeight) +uint256 CClaimTrieCacheBase::computeNodeHash(const std::string& name, uint256& claimsHash, int takeoverHeight) { const auto pos = name.size(); std::vector vchToHash; @@ -449,11 +474,13 @@ uint256 CClaimTrieCacheBase::computeNodeHash(const std::string& name, int takeov childHashQuery++; if (takeoverHeight > 0) { - CClaimValue claim; - if (getInfoForName(name, claim)) { - auto valueHash = getValueHash(claim.outPoint, takeoverHeight); - vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end()); + if (claimsHash.IsNull()) { + CClaimValue claim; + if (getInfoForName(name, claim)) + claimsHash = getValueHash(claim.outPoint, takeoverHeight); } + if (!claimsHash.IsNull()) + vchToHash.insert(vchToHash.end(), claimsHash.begin(), claimsHash.end()); } return vchToHash.empty() ? one : Hash(vchToHash.begin(), vchToHash.end()); @@ -471,22 +498,47 @@ bool CClaimTrieCacheBase::checkConsistency() } } + if (base->isNodeMigrationStart) + ensureTransacting(); + + auto updateQuery = db << "UPDATE node SET claimsHash = ? WHERE name = ?"; // not checking everything as it takes too long - auto query = db << "SELECT n.name, n.hash, " + auto query = db << (base->isNodeMigrationStart ? + "SELECT n.name, n.hash, n.claimsHash, " "IFNULL((SELECT CASE WHEN t.claimID IS NULL THEN 0 ELSE t.height END " - "FROM takeover t WHERE t.name = n.name ORDER BY t.height DESC LIMIT 1), 0) FROM node n " - "WHERE n.name IN (SELECT r.name FROM node r ORDER BY RANDOM() LIMIT 100000) OR n.parent = x''"; + "FROM takeover t WHERE t.name = n.name ORDER BY t.height DESC LIMIT 1), 0) " + "FROM node n ORDER BY LENGTH(n.name) DESC" + : + "SELECT n.name, n.hash, n.claimsHash, " + "IFNULL((SELECT CASE WHEN t.claimID IS NULL THEN 0 ELSE t.height END " + "FROM takeover t WHERE t.name = n.name ORDER BY t.height DESC LIMIT 1), 0) " + "FROM node n WHERE n.name IN " + "(SELECT r.name FROM node r ORDER BY RANDOM() LIMIT 100000) OR n.parent = x''"); for (auto&& row: query) { std::string name; - uint256 hash; int takeoverHeight; - row >> name >> hash >> takeoverHeight; - auto computedHash = computeNodeHash(name, takeoverHeight); + uint256 hash, claimsHash, computedClaimsHash; + row >> name >> hash >> claimsHash >> takeoverHeight; + auto computedHash = computeNodeHash(name, computedClaimsHash, takeoverHeight); if (computedHash != hash) { logPrint << "Invalid hash at " << name << Clog::endl; return false; } + if (base->isNodeMigrationStart) { + assert(!computedClaimsHash.IsNull()); + updateQuery << computedClaimsHash << name; + updateQuery++; + } else if (computedClaimsHash != claimsHash) { + logPrint << "Invalid claimsHash at " << name << Clog::endl; + return false; + } } + + updateQuery.used(true); + + if (base->isNodeMigrationStart) + return flush(); + return true; } @@ -572,20 +624,20 @@ uint256 CClaimTrieCacheBase::getMerkleHash() { ensureTreeStructureIsUpToDate(); uint256 hash; - db << "SELECT hash FROM node WHERE name = x''" - >> [&hash](std::unique_ptr rootHash) { - if (rootHash) - hash = std::move(*rootHash); - }; - if (!hash.IsNull()) - return hash; + for (auto&& row : db << "SELECT hash FROM node WHERE name = x''") { + row >> hash; + if (!hash.IsNull()) + return hash; + } assert(transacting); // no data changed but we didn't have the root hash there already? - auto updateQuery = db << "UPDATE node SET hash = ? WHERE name = ?"; - db << "SELECT n.name, IFNULL((SELECT CASE WHEN t.claimID IS NULL THEN 0 ELSE t.height END FROM takeover t WHERE t.name = n.name " - "ORDER BY t.height DESC LIMIT 1), 0) FROM node n WHERE n.hash IS NULL ORDER BY LENGTH(n.name) DESC" // assumes n.name is blob - >> [this, &hash, &updateQuery](const std::string& name, int takeoverHeight) { - hash = computeNodeHash(name, takeoverHeight); - updateQuery << hash << name; + auto updateQuery = db << "UPDATE node SET hash = ?, claimsHash = ? WHERE name = ?"; + db << "SELECT n.name, n.claimsHash, " + "IFNULL((SELECT CASE WHEN t.claimID IS NULL THEN 0 ELSE t.height END " + "FROM takeover t WHERE t.name = n.name ORDER BY t.height DESC LIMIT 1), 0) " + "FROM node n WHERE n.hash IS NULL ORDER BY LENGTH(n.name) DESC" // assumes n.name is blob + >> [&](const std::string& name, uint256 claimsHash, int takeoverHeight) { + hash = computeNodeHash(name, claimsHash, takeoverHeight); + updateQuery << hash << claimsHash << name; updateQuery++; }; updateQuery.used(true); @@ -639,7 +691,7 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& out << originalHeight << nHeight << nValidHeight << nValidHeight << expires; if (nValidHeight < nNextHeight) - db << "INSERT INTO node(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName; + db << "INSERT INTO node(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL, claimsHash = NULL" << nodeName; return true; } @@ -660,7 +712,7 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const COutPoint& o << supportedClaimId << name << nodeName << outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << nValidHeight << expires; if (nValidHeight < nNextHeight) - db << "UPDATE node SET hash = NULL WHERE name = ?" << nodeName; + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name = ?" << nodeName; return true; } @@ -691,7 +743,7 @@ bool CClaimTrieCacheBase::removeClaim(const uint160& claimId, const COutPoint& o if (!db.rows_modified()) return false; - db << "UPDATE node SET hash = NULL WHERE name = ?" << nodeName; + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name = ?" << nodeName; // when node should be deleted from cache but instead it's kept // because it's a parent one and should not be effectively erased @@ -722,7 +774,8 @@ bool CClaimTrieCacheBase::removeSupport(const COutPoint& outPoint, std::string& db << "DELETE FROM support WHERE txID = ? AND txN = ?" << outPoint.hash << outPoint.n; if (!db.rows_modified()) return false; - db << "UPDATE node SET hash = NULL WHERE name = ?" << nodeName; + + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name = ?" << nodeName; return true; } @@ -739,11 +792,11 @@ bool CClaimTrieCacheBase::incrementBlock() db << "INSERT INTO node(name) SELECT nodeName FROM claim INDEXED BY claim_activationHeight " "WHERE activationHeight = ?1 AND expirationHeight > ?1 " - "ON CONFLICT(name) DO UPDATE SET hash = NULL" + "ON CONFLICT(name) DO UPDATE SET hash = NULL, claimsHash = NULL" << nNextHeight; // don't make new nodes for items in supports or items that expire this block that don't exist in claims - db << "UPDATE node SET hash = NULL WHERE name IN " + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name IN " "(SELECT nodeName FROM claim WHERE expirationHeight = ?1 " "UNION SELECT nodeName FROM support WHERE expirationHeight = ?1 OR activationHeight = ?1)" << nNextHeight; @@ -818,10 +871,10 @@ bool CClaimTrieCacheBase::decrementBlock() nNextHeight--; db << "INSERT INTO node(name) SELECT nodeName FROM claim " - "WHERE expirationHeight = ? ON CONFLICT(name) DO UPDATE SET hash = NULL" + "WHERE expirationHeight = ? ON CONFLICT(name) DO UPDATE SET hash = NULL, claimsHash = NULL" << nNextHeight; - db << "UPDATE node SET hash = NULL WHERE name IN(" + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name IN(" "SELECT nodeName FROM support WHERE expirationHeight = ?1 OR activationHeight = ?1 " "UNION SELECT nodeName FROM claim WHERE activationHeight = ?1)" << nNextHeight; @@ -837,7 +890,7 @@ bool CClaimTrieCacheBase::decrementBlock() bool CClaimTrieCacheBase::finalizeDecrement() { - db << "UPDATE node SET hash = NULL WHERE name IN " + db << "UPDATE node SET hash = NULL, claimsHash = NULL WHERE name IN " "(SELECT nodeName FROM claim WHERE activationHeight = ?1 AND expirationHeight > ?1 " "UNION SELECT nodeName FROM support WHERE activationHeight = ?1 AND expirationHeight > ?1 " "UNION SELECT name FROM takeover WHERE height = ?1)" << nNextHeight; diff --git a/src/claimtrie/trie.h b/src/claimtrie/trie.h index c0b2fb20b..1433bf040 100644 --- a/src/claimtrie/trie.h +++ b/src/claimtrie/trie.h @@ -49,6 +49,7 @@ protected: std::size_t dbCacheBytes; const std::string dbFile; sqlite::database db; + bool isNodeMigrationStart; const int nProportionalDelayFactor; const int nNormalizedNameForkHeight; @@ -57,6 +58,9 @@ protected: const int64_t nExtendedClaimExpirationTime; const int64_t nExtendedClaimExpirationForkHeight; const int64_t nAllClaimsInMerkleForkHeight; + +private: + void doNodeTableMigration(); }; class CClaimTrieCacheBase @@ -119,7 +123,7 @@ protected: mutable sqlite::database_binder claimHashQuery, childHashQuery, claimHashQueryLimit; - virtual uint256 computeNodeHash(const std::string& name, int takeoverHeight); + virtual uint256 computeNodeHash(const std::string& name, uint256& claimsHash, int takeoverHeight); supportEntryType getSupportsForName(const std::string& name) const; virtual int getDelayForName(const std::string& name, const uint160& claimId) const; diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 2a76d0d46..18db5171a 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/src/validation.cpp b/src/validation.cpp index 795e24bf8..faedb3746 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2059,15 +2059,15 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl // TODO: if the "just check" flag is set, we should reduce the work done here. Incrementing blocks twice per mine is not efficient. assert(trieCache.incrementBlock()); + int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2; + LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal); + if (trieCache.getMerkleHash() != block.hashClaimTrie) { return state.DoS(100, error("ConnectBlock() : the merkle root of the claim trie does not match " "(actual=%s vs block=%s on height=%d)", trieCache.getMerkleHash().GetHex(), block.hashClaimTrie.GetHex(), pindex->nHeight), REJECT_INVALID, "bad-claim-merkle-hash"); } - int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2; - LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal); - CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); if (block.vtx[0]->GetValueOut() > blockReward) return state.DoS(100, @@ -2077,8 +2077,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl if (!control.Wait()) return state.DoS(100, error("%s: CheckQueue failed", __func__), REJECT_INVALID, "block-validation-failed"); - int64_t nTime4 = GetTimeMicros(); nTimeVerify += nTime4 - nTime2; - LogPrint(BCLog::BENCH, " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1, MILLI * (nTime4 - nTime2), nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal); + int64_t nTime4 = GetTimeMicros(); nTimeVerify += nTime4 - nTime3; + LogPrint(BCLog::BENCH, " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1, MILLI * (nTime4 - nTime3), nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime3) / (nInputs-1), nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal); if (fJustCheck) return true; From fc5a0078b086c407c18e08842c78f713e8393bb9 Mon Sep 17 00:00:00 2001 From: Anthony Fieroni Date: Tue, 9 Jun 2020 16:21:26 +0300 Subject: [PATCH 2/2] Increase default db cache, optimize db before sync Signed-off-by: Anthony Fieroni --- src/claimtrie/trie.cpp | 1 + src/txdb.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/claimtrie/trie.cpp b/src/claimtrie/trie.cpp index 5b614b393..4fd229a78 100644 --- a/src/claimtrie/trie.cpp +++ b/src/claimtrie/trie.cpp @@ -155,6 +155,7 @@ CClaimTrieCacheBase::~CClaimTrieCacheBase() bool CClaimTrie::SyncToDisk() { + db << "PRAGMA optimize"; // alternatively, switch to full sync after we are caught up on the chain return sqlite::sync(db) == SQLITE_OK; } diff --git a/src/txdb.h b/src/txdb.h index 51dbcf9f6..d1deb3004 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -58,7 +58,7 @@ class uint256; //! No need to periodic flush if at least this much space still available. static constexpr int MAX_BLOCK_COINSDB_USAGE = 10; //! -dbcache default (MiB) -static const int64_t nDefaultDbCache = 480; +static const int64_t nDefaultDbCache = 4096; //! -dbbatchsize default (bytes) static const int64_t nDefaultDbBatchSize = 16 << 20; //! max. -dbcache (MiB)