From 6b22f6632594d9359cafb41cad3bdb9a7ca5c83f Mon Sep 17 00:00:00 2001 From: Brannon King Date: Mon, 4 Nov 2019 14:23:13 -0700 Subject: [PATCH] cache and hash fork tests pass --- src/claimtrie.cpp | 32 ++++++++++--------- src/claimtrie.h | 12 +++---- src/claimtrieforks.cpp | 8 ++--- src/test/claimtriecache_tests.cpp | 53 ------------------------------- 4 files changed, 26 insertions(+), 79 deletions(-) diff --git a/src/claimtrie.cpp b/src/claimtrie.cpp index 83eb64da8..4b6e875ad 100644 --- a/src/claimtrie.cpp +++ b/src/claimtrie.cpp @@ -50,29 +50,29 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, int proportionalDelayFactor) : dbPath((GetDataDir() / "claims.sqlite").string()), db(dbPath, sharedConfig), nNextHeight(height), nProportionalDelayFactor(proportionalDelayFactor) { - db.define("MERKLE_ROOT", [](std::vector& hashes, const std::vector& blob) { hashes.emplace_back(uint256(blob)); }, - [](const std::vector& hashes) { return ComputeMerkleRoot(hashes); }); +// db.define("MERKLE_ROOT", [](std::vector& hashes, const std::vector& blob) { hashes.emplace_back(uint256(blob)); }, +// [](const std::vector& hashes) { return ComputeMerkleRoot(hashes); }); +// +// db.define("MERKLE_PAIR", [](const std::vector& blob1, const std::vector& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); }); +// db.define("MERKLE", [](const std::vector& blob1) { return Hash(blob1.begin(), blob1.end()); }); - db.define("MERKLE_PAIR", [](const std::vector& blob1, const std::vector& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); }); - db.define("MERKLE", [](const std::vector& blob1) { return Hash(blob1.begin(), blob1.end()); }); - - db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB, takeoverHeight INTEGER, takeoverID BLOB)"; + db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB COLLATE BINARY, takeoverHeight INTEGER, takeoverID BLOB COLLATE BINARY)"; db << "CREATE INDEX IF NOT EXISTS nodes_hash ON nodes (hash)"; db << "CREATE INDEX IF NOT EXISTS nodes_parent ON nodes (parent)"; - db << "CREATE TABLE IF NOT EXISTS claims (claimID BLOB NOT NULL PRIMARY KEY, name TEXT NOT NULL, " + db << "CREATE TABLE IF NOT EXISTS claims (claimID BLOB NOT NULL COLLATE BINARY PRIMARY KEY, name TEXT NOT NULL, " "nodeName TEXT NOT NULL REFERENCES nodes(name) DEFERRABLE INITIALLY DEFERRED, " - "txID BLOB NOT NULL, txN INTEGER NOT NULL, blockHeight INTEGER NOT NULL, " + "txID BLOB NOT NULL COLLATE BINARY, txN INTEGER NOT NULL, blockHeight INTEGER NOT NULL, " "validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, " - "amount INTEGER NOT NULL, metadata BLOB);"; + "amount INTEGER NOT NULL, metadata BLOB COLLATE BINARY);"; db << "CREATE INDEX IF NOT EXISTS claims_validHeight ON claims (validHeight)"; db << "CREATE INDEX IF NOT EXISTS claims_expirationHeight ON claims (expirationHeight)"; db << "CREATE INDEX IF NOT EXISTS claims_nodeName ON claims (nodeName)"; - db << "CREATE TABLE IF NOT EXISTS supports (txID BLOB NOT NULL, txN INTEGER NOT NULL, " - "supportedClaimID BLOB NOT NULL, name TEXT NOT NULL, nodeName TEXT NOT NULL, " + db << "CREATE TABLE IF NOT EXISTS supports (txID BLOB NOT NULL COLLATE BINARY, txN INTEGER NOT NULL, " + "supportedClaimID BLOB NOT NULL COLLATE BINARY, name TEXT NOT NULL, nodeName TEXT NOT NULL, " "blockHeight INTEGER NOT NULL, validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, " - "amount INTEGER NOT NULL, metadata BLOB, PRIMARY KEY(txID, txN));"; + "amount INTEGER NOT NULL, metadata BLOB COLLATE BINARY, PRIMARY KEY(txID, txN));"; db << "CREATE INDEX IF NOT EXISTS supports_supportedClaimID ON supports (supportedClaimID)"; db << "CREATE INDEX IF NOT EXISTS supports_validHeight ON supports (validHeight)"; db << "CREATE INDEX IF NOT EXISTS supports_expirationHeight ON supports (expirationHeight)"; @@ -230,7 +230,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() { auto parentQuery = db << "SELECT name FROM nodes WHERE " "name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL " "SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) " - "ORDER BY LENGTH(name) DESC LIMIT 1"; + "ORDER BY name DESC LIMIT 1"; for (auto& name: names) { std::vector claims; @@ -328,7 +328,7 @@ bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& c auto query = db << "SELECT c.claimID, c.txID, c.txN, c.blockHeight, c.validHeight, c.amount, " "(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount " "FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? " - "ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN LIMIT 1" + "ORDER BY effectiveAmount DESC, c.blockHeight, REVERSE_BYTES(c.txID), c.txN LIMIT 1" << nextHeight << nextHeight << name << nextHeight << nextHeight; for (auto&& row: query) { row >> claim.claimId >> claim.outPoint.hash >> claim.outPoint.n @@ -493,6 +493,8 @@ CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base) db << "PRAGMA journal_mode=MEMORY"; db << "PRAGMA temp_store=MEMORY"; db << "PRAGMA case_sensitive_like=true"; + + db.define("REVERSE_BYTES", [](std::vector blob) { std::reverse(blob.begin(), blob.end()); return blob; }); } int CClaimTrieCacheBase::expirationTime() const @@ -1256,7 +1258,7 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160 auto nodeQuery = db << "SELECT name, IFNULL(takeoverHeight, 0) FROM nodes WHERE " "name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL " "SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) " - "ORDER BY LENGTH(name)" << name; + "ORDER BY name" << name; for (auto&& row: nodeQuery) { CClaimValue claim; std::string key; diff --git a/src/claimtrie.h b/src/claimtrie.h index 5803b7c80..4a3cc72b3 100644 --- a/src/claimtrie.h +++ b/src/claimtrie.h @@ -20,18 +20,16 @@ namespace sqlite { - inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint160& vec) { - void const* buf = reinterpret_cast(vec.begin()); - return sqlite3_bind_blob(stmt, inx, buf, int(vec.size()), SQLITE_STATIC); + inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint160& val) { + return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC); } - inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint256& vec) { - void const* buf = reinterpret_cast(vec.begin()); - return sqlite3_bind_blob(stmt, inx, buf, int(vec.size()), SQLITE_STATIC); + inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint256& val) { + return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC); } inline void store_result_in_db(sqlite3_context* db, const uint160& val) { - sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT); + sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT); // I think we need transient here but I'm not 100% sure } inline void store_result_in_db(sqlite3_context* db, const uint256& val) { diff --git a/src/claimtrieforks.cpp b/src/claimtrieforks.cpp index 1926e7975..e24afa028 100644 --- a/src/claimtrieforks.cpp +++ b/src/claimtrieforks.cpp @@ -264,7 +264,7 @@ uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& n "(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID " "AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount " "FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? " - "ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN" + "ORDER BY effectiveAmount DESC, c.blockHeight, REVERSE_BYTES(c.txID), c.txN" << nNextHeight << nNextHeight << name << nNextHeight << nNextHeight; std::vector claimHashes; @@ -363,7 +363,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin row >> key >> takeoverHeight; std::vector childHashes; uint32_t nextCurrentIdx = 0; - auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ?" << key; + auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ? ORDER BY name" << key; for (auto&& child : childQuery) { std::string childKey; uint256 childHash; @@ -377,8 +377,8 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin "(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID " "AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount " "FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? " - "ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN" - << nNextHeight << nNextHeight << name << nNextHeight << nNextHeight; + "ORDER BY effectiveAmount DESC, c.blockHeight, REVERSE_BYTES(c.txID), c.txN" + << nNextHeight << nNextHeight << key << nNextHeight << nNextHeight; std::vector claimHashes; uint32_t finalClaimIdx = 0; diff --git a/src/test/claimtriecache_tests.cpp b/src/test/claimtriecache_tests.cpp index 220e4cc0e..bd087461a 100644 --- a/src/test/claimtriecache_tests.cpp +++ b/src/test/claimtriecache_tests.cpp @@ -326,59 +326,6 @@ BOOST_AUTO_TEST_CASE(trie_stays_consistent_test) BOOST_CHECK(trie.empty()); } -BOOST_AUTO_TEST_CASE(takeover_workaround_triggers) -{ - auto& consensus = const_cast(Params().GetConsensus()); - auto currentMax = consensus.nMaxTakeoverWorkaroundHeight; - consensus.nMaxTakeoverWorkaroundHeight = 10000; - BOOST_SCOPE_EXIT(&consensus, currentMax) { consensus.nMaxTakeoverWorkaroundHeight = currentMax; } - BOOST_SCOPE_EXIT_END - - CClaimTrie trie(false, 0, 1); - CClaimTrieCacheTest cache(&trie); - - insertUndoType icu, isu; claimUndoType ecu; supportUndoType esu; takeoverUndoType tut; - BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut)); - - CClaimValue value; - value.nHeight = 1; - - BOOST_CHECK(cache.insertClaimIntoTrie("a", value)); - BOOST_CHECK(cache.insertClaimIntoTrie("b", value)); - BOOST_CHECK(cache.insertClaimIntoTrie("c", value)); - BOOST_CHECK(cache.insertClaimIntoTrie("aa", value)); - BOOST_CHECK(cache.insertClaimIntoTrie("bb", value)); - BOOST_CHECK(cache.insertClaimIntoTrie("cc", value)); - BOOST_CHECK(cache.insertSupportIntoMap("aa", CSupportValue())); - - BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut)); - BOOST_CHECK(cache.flush()); - BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut)); - - CSupportValue temp; - CClaimValue cv; - BOOST_CHECK(cache.insertSupportIntoMap("bb", temp)); - BOOST_CHECK(!cache.getInfoForName("aa", cv)); - BOOST_CHECK(cache.removeSupportFromMap("aa", COutPoint())); - - BOOST_CHECK(cache.removeClaimFromTrie("aa", COutPoint())); - BOOST_CHECK(cache.removeClaimFromTrie("bb", COutPoint())); - BOOST_CHECK(cache.removeClaimFromTrie("cc", COutPoint())); - - BOOST_CHECK(cache.insertClaimIntoTrie("aa", value)); - BOOST_CHECK(cache.insertClaimIntoTrie("bb", value)); - BOOST_CHECK(cache.insertClaimIntoTrie("cc", value)); - - BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut)); - - BOOST_CHECK(cache.getInfoForName("aa", cv)); - BOOST_CHECK_EQUAL(3, cv.nValidAtHeight); - BOOST_CHECK(cache.getInfoForName("bb", cv)); - BOOST_CHECK_EQUAL(3, cv.nValidAtHeight); - BOOST_CHECK(cache.getInfoForName("cc", cv)); - BOOST_CHECK_EQUAL(1, cv.nValidAtHeight); -} - BOOST_AUTO_TEST_CASE(verify_basic_serialization) { CClaimValue cv;