diff --git a/src/claimtrie/forks.cpp b/src/claimtrie/forks.cpp index 1d50d4032..58db08926 100644 --- a/src/claimtrie/forks.cpp +++ b/src/claimtrie/forks.cpp @@ -25,19 +25,18 @@ int CClaimTrieCacheExpirationFork::expirationTime() const return base->nExtendedClaimExpirationTime; } -bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo) +bool CClaimTrieCacheExpirationFork::incrementBlock() { - if (CClaimTrieCacheBase::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo)) { + if (CClaimTrieCacheBase::incrementBlock()) { expirationHeight = nNextHeight; return true; } return false; } -bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo) +bool CClaimTrieCacheExpirationFork::decrementBlock() { - if (CClaimTrieCacheBase::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) { + if (CClaimTrieCacheBase::decrementBlock()) { expirationHeight = nNextHeight; return true; } @@ -53,9 +52,9 @@ void CClaimTrieCacheExpirationFork::initializeIncrement() forkForExpirationChange(true); } -bool CClaimTrieCacheExpirationFork::finalizeDecrement(takeoverUndoType& takeoverUndo) +bool CClaimTrieCacheExpirationFork::finalizeDecrement() { - auto ret = CClaimTrieCacheBase::finalizeDecrement(takeoverUndo); + auto ret = CClaimTrieCacheBase::finalizeDecrement(); if (ret && nNextHeight == base->nExtendedClaimExpirationForkHeight) forkForExpirationChange(false); return ret; @@ -137,41 +136,30 @@ std::string CClaimTrieCacheNormalizationFork::normalizeClaimName(const std::stri return normalized; } -bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(takeoverUndoType& takeoverUndo) +bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary() { ensureTransacting(); // make the new nodes - db << "INSERT INTO nodes(name) SELECT NORMALIZED(name) AS nn FROM claims WHERE nn != nodeName " - "AND validHeight <= ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight; - - db << "UPDATE nodes SET hash = NULL WHERE name IN " - "(SELECT NORMALIZED(name) AS nn FROM supports WHERE nn != nodeName " - "AND validHeight <= ?1 AND expirationHeight > ?1)" << nNextHeight; + db << "INSERT INTO nodes(name) " + "SELECT NORMALIZED(name) AS nc FROM claims WHERE nc != nodeName " + "AND activationHeight <= ?1 AND expirationHeight > ?1 " + "UNION SELECT NORMALIZED(name) AS ns FROM supports WHERE ns != nodeName " + "AND activationHeight <= ?1 AND expirationHeight > ?1 " + "ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight; // update the claims and supports - db << "UPDATE claims SET nodeName = NORMALIZED(name) WHERE validHeight <= ?1 AND expirationHeight > ?1" << nNextHeight; - db << "UPDATE supports SET nodeName = NORMALIZED(name) WHERE validHeight <= ?1 AND expirationHeight > ?1" << nNextHeight; + db << "UPDATE claims SET nodeName = NORMALIZED(name) WHERE activationHeight <= ?1 AND expirationHeight > ?1" << nNextHeight; + db << "UPDATE supports SET nodeName = NORMALIZED(name) WHERE activationHeight <= ?1 AND expirationHeight > ?1" << nNextHeight; // remove the old nodes - auto query = db << "SELECT name, IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name NOT IN " - "(SELECT nodeName FROM claims WHERE validHeight <= ?1 AND expirationHeight > ?1)"; - for (auto&& row: query) { - std::string name; - int takeoverHeight; - std::unique_ptr takeoverID; - row >> name >> takeoverHeight >> takeoverID; - if (name.empty()) continue; // preserve our root node - if (takeoverHeight > 0) - takeoverUndo.emplace_back(name, std::make_pair(takeoverHeight, takeoverID ? *takeoverID : CUint160())); - // we need to let the tree structure method do the actual node delete: - db << "UPDATE nodes SET hash = NULL WHERE name = ?" << name; - } - db << "UPDATE nodes SET hash = NULL WHERE takeoverHeight IS NULL"; + db << "UPDATE nodes SET hash = NULL WHERE name NOT IN " + "(SELECT nodeName FROM claims WHERE activationHeight <= ?1 AND expirationHeight > ?1 " + "UNION SELECT nodeName FROM supports WHERE activationHeight <= ?1 AND expirationHeight > ?1)" << nNextHeight; // work around a bug in the old implementation: - db << "UPDATE claims SET validHeight = ?1 " // force a takeover on these - "WHERE blockHeight < ?1 AND validHeight > ?1 AND nodeName != name" << nNextHeight; + db << "UPDATE claims SET activationHeight = ?1 " // force a takeover on these + "WHERE blockHeight < ?1 AND activationHeight > ?1 AND nodeName != name" << nNextHeight; return true; } @@ -180,34 +168,37 @@ bool CClaimTrieCacheNormalizationFork::unnormalizeAllNamesInTrieIfNecessary() { ensureTransacting(); - db << "INSERT INTO nodes(name) SELECT name FROM claims WHERE name != nodeName " - "AND validHeight < ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight; + db << "INSERT INTO nodes(name) " + "SELECT name FROM claims WHERE name != nodeName " + "AND activationHeight < ?1 AND expirationHeight > ?1 " + "UNION SELECT name FROM supports WHERE name != nodeName " + "AND activationHeight < ?1 AND expirationHeight > ?1 " + "ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight; db << "UPDATE nodes SET hash = NULL WHERE name IN " - "(SELECT name FROM supports WHERE name != nodeName UNION " - "SELECT nodeName FROM supports WHERE name != nodeName UNION " - "SELECT nodeName FROM claims WHERE name != nodeName)"; + "(SELECT nodeName FROM supports WHERE name != nodeName " + "UNION SELECT nodeName FROM claims WHERE name != nodeName)"; db << "UPDATE claims SET nodeName = name"; db << "UPDATE supports SET nodeName = name"; + // we need to let the tree structure method do the actual node delete db << "UPDATE nodes SET hash = NULL WHERE name NOT IN " - "(SELECT name FROM claims)"; + "(SELECT DISTINCT name FROM claims)"; return true; } -bool CClaimTrieCacheNormalizationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo) +bool CClaimTrieCacheNormalizationFork::incrementBlock() { if (nNextHeight == base->nNormalizedNameForkHeight) - normalizeAllNamesInTrieIfNecessary(takeoverUndo); - return CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo); + normalizeAllNamesInTrieIfNecessary(); + return CClaimTrieCacheExpirationFork::incrementBlock(); } -bool CClaimTrieCacheNormalizationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo) +bool CClaimTrieCacheNormalizationFork::decrementBlock() { - auto ret = CClaimTrieCacheExpirationFork::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo); + auto ret = CClaimTrieCacheExpirationFork::decrementBlock(); if (ret && nNextHeight == base->nNormalizedNameForkHeight) unnormalizeAllNamesInTrieIfNecessary(); return ret; @@ -417,9 +408,9 @@ void CClaimTrieCacheHashFork::initializeIncrement() } } -bool CClaimTrieCacheHashFork::finalizeDecrement(takeoverUndoType& takeoverUndo) +bool CClaimTrieCacheHashFork::finalizeDecrement() { - auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement(takeoverUndo); + auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement(); if (ret && nNextHeight == base->nAllClaimsInMerkleForkHeight - 1) { ensureTransacting(); db << "UPDATE nodes SET hash = NULL"; diff --git a/src/claimtrie/forks.h b/src/claimtrie/forks.h index cd167bb9f..b81424eaf 100644 --- a/src/claimtrie/forks.h +++ b/src/claimtrie/forks.h @@ -12,18 +12,9 @@ public: int expirationTime() const override; virtual void initializeIncrement(); - bool finalizeDecrement(takeoverUndoType& takeoverHeightUndo) override; - - bool incrementBlock(insertUndoType& insertUndo, - claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, - supportUndoType& expireSupportUndo, - takeoverUndoType& takeoverHeightUndo) override; - - bool decrementBlock(insertUndoType& insertUndo, - claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, - supportUndoType& expireSupportUndo) override; + bool incrementBlock() override; + bool decrementBlock() override; + bool finalizeDecrement() override; protected: int expirationHeight; @@ -43,16 +34,8 @@ public: // see: https://unicode.org/reports/tr15/#Norm_Forms std::string normalizeClaimName(const std::string& name, bool force = false) const; // public only for validating name field on update op - bool incrementBlock(insertUndoType& insertUndo, - claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, - supportUndoType& expireSupportUndo, - takeoverUndoType& takeoverHeightUndo) override; - - bool decrementBlock(insertUndoType& insertUndo, - claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, - supportUndoType& expireSupportUndo) override; + bool incrementBlock() override; + bool decrementBlock() override; bool getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof) override; bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const override; @@ -63,7 +46,7 @@ protected: int getDelayForName(const std::string& name, const CUint160& claimId) const override; private: - bool normalizeAllNamesInTrieIfNecessary(takeoverUndoType& takeovers); + bool normalizeAllNamesInTrieIfNecessary(); bool unnormalizeAllNamesInTrieIfNecessary(); }; @@ -74,7 +57,7 @@ public: bool getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof) override; void initializeIncrement() override; - bool finalizeDecrement(takeoverUndoType& takeoverHeightUndo) override; + bool finalizeDecrement() override; bool allowSupportMetadata() const; diff --git a/src/claimtrie/libclaimtrie.i b/src/claimtrie/libclaimtrie.i index 47d996b5b..654185451 100644 --- a/src/claimtrie/libclaimtrie.i +++ b/src/claimtrie/libclaimtrie.i @@ -25,8 +25,6 @@ %ignore CSupportValue(CSupportValue &&); %ignore CTxOutPoint(CTxOutPoint &&); -#define SWIG_INTERFACE - %include "uints.h" %include "txoutpoint.h" %include "data.h" @@ -45,19 +43,11 @@ %template(claimsNsupports) std::vector; %template(proofPair) std::pair; -%template(intClaimPair) std::pair; %template(proofNodePair) std::pair; -%template(claimUndoPair) std::pair; -%template(supportUndoPair) std::pair; -%template(takeoverUndoPair) std::pair>; %template(proofNodes) std::vector; %template(proofPairs) std::vector>; %template(proofNodeChildren) std::vector>; -%template(claimUndoType) std::vector; -%template(supportUndoType) std::vector; -%template(insertUndoType) std::vector; -%template(takeoverUndoType) std::vector; %inline %{ struct CIterateCallback { @@ -74,6 +64,6 @@ void getNamesInTrie(const CClaimTrieCache& cache, CIterateCallback* cb) } %} -%typemap(in,numinputs=0) CClaimValue&, CClaimTrieProof&, insertUndoType&, claimUndoType&, supportUndoType&, takeoverUndoType& %{ +%typemap(in,numinputs=0) CClaimValue&, CClaimTrieProof& %{ $1 = &$input; %} diff --git a/src/claimtrie/trie.cpp b/src/claimtrie/trie.cpp index 841f00ecc..a47b4984a 100644 --- a/src/claimtrie/trie.cpp +++ b/src/claimtrie/trie.cpp @@ -59,29 +59,36 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, nExtendedClaimExpirationForkHeight(nExtendedClaimExpirationForkHeight), nAllClaimsInMerkleForkHeight(nAllClaimsInMerkleForkHeight) { - db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT REFERENCES nodes(name) DEFERRABLE INITIALLY DEFERRED, " - "hash BLOB COLLATE BINARY, takeoverHeight INTEGER, takeoverID BLOB COLLATE BINARY)"; + db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, " + "parent TEXT REFERENCES nodes(name) DEFERRABLE INITIALLY DEFERRED, " + "hash 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 takeover (name TEXT NOT NULL, height INTEGER NOT NULL, " + "claimID BLOB COLLATE BINARY, UNIQUE (name, height, claimID));"; + + db << "CREATE INDEX IF NOT EXISTS takeover_name ON takeover (name)"; + db << "CREATE INDEX IF NOT EXISTS takeover_height ON takeover (height)"; + 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 COLLATE BINARY, txN INTEGER NOT NULL, blockHeight INTEGER NOT NULL, " - "validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, " - "amount INTEGER NOT NULL, metadata BLOB COLLATE BINARY);"; + "validHeight INTEGER NOT NULL, activationHeight INTEGER NOT NULL, " + "expirationHeight INTEGER NOT NULL, 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_activationHeight ON claims (activationHeight)"; 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 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 COLLATE BINARY, PRIMARY KEY(txID, txN));"; + "blockHeight INTEGER NOT NULL, validHeight INTEGER NOT NULL, activationHeight INTEGER NOT NULL, " + "expirationHeight INTEGER NOT NULL, 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_activationHeight ON supports (activationHeight)"; db << "CREATE INDEX IF NOT EXISTS supports_expirationHeight ON supports (expirationHeight)"; db << "CREATE INDEX IF NOT EXISTS supports_nodeName ON supports (nodeName)"; @@ -95,6 +102,7 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, db << "DELETE FROM nodes"; db << "DELETE FROM claims"; db << "DELETE FROM supports"; + db << "DELETE FROM takeover"; } db << "INSERT OR IGNORE INTO nodes(name, hash) VALUES('', ?)" << one; // ensure that we always have our root node @@ -120,14 +128,14 @@ bool CClaimTrie::SyncToDisk() bool CClaimTrie::empty() { int64_t count; - db << "SELECT COUNT(*) FROM (SELECT 1 FROM claims WHERE validHeight < ?1 AND expirationHeight >= ?1 LIMIT 1)" << nNextHeight >> count; + db << "SELECT COUNT(*) FROM (SELECT 1 FROM claims WHERE activationHeight < ?1 AND expirationHeight >= ?1 LIMIT 1)" << nNextHeight >> count; return count == 0; } bool CClaimTrieCacheBase::haveClaim(const std::string& name, const CTxOutPoint& outPoint) const { auto query = db << "SELECT 1 FROM claims WHERE nodeName = ?1 AND txID = ?2 AND txN = ?3 " - "AND validHeight < ?4 AND expirationHeight >= ?4 LIMIT 1" + "AND activationHeight < ?4 AND expirationHeight >= ?4 LIMIT 1" << name << outPoint.hash << outPoint.n << nNextHeight; return query.begin() != query.end(); } @@ -135,7 +143,7 @@ bool CClaimTrieCacheBase::haveClaim(const std::string& name, const CTxOutPoint& bool CClaimTrieCacheBase::haveSupport(const std::string& name, const CTxOutPoint& outPoint) const { auto query = db << "SELECT 1 FROM supports WHERE nodeName = ?1 AND txID = ?2 AND txN = ?3 " - "AND validHeight < ?4 AND expirationHeight >= ?4 LIMIT 1" + "AND activationHeight < ?4 AND expirationHeight >= ?4 LIMIT 1" << name << outPoint.hash << outPoint.n << nNextHeight; return query.begin() != query.end(); } @@ -143,7 +151,7 @@ bool CClaimTrieCacheBase::haveSupport(const std::string& name, const CTxOutPoint supportEntryType CClaimTrieCacheBase::getSupportsForName(const std::string& name) const { // includes values that are not yet valid - auto query = db << "SELECT supportedClaimID, txID, txN, blockHeight, validHeight, amount " + auto query = db << "SELECT supportedClaimID, txID, txN, blockHeight, activationHeight, amount " "FROM supports WHERE nodeName = ? AND expirationHeight >= ?" << name << nNextHeight; supportEntryType ret; for (auto&& row: query) { @@ -157,8 +165,8 @@ supportEntryType CClaimTrieCacheBase::getSupportsForName(const std::string& name bool CClaimTrieCacheBase::haveClaimInQueue(const std::string& name, const CTxOutPoint& outPoint, int& nValidAtHeight) const { - auto query = db << "SELECT validHeight FROM claims WHERE nodeName = ? AND txID = ? AND txN = ? " - "AND validHeight >= ? AND expirationHeight >= validHeight LIMIT 1" + auto query = db << "SELECT activationHeight FROM claims WHERE nodeName = ? AND txID = ? AND txN = ? " + "AND activationHeight >= ? AND expirationHeight >= activationHeight LIMIT 1" << name << outPoint.hash << outPoint.n << nNextHeight; for (auto&& row: query) { row >> nValidAtHeight; @@ -169,8 +177,8 @@ bool CClaimTrieCacheBase::haveClaimInQueue(const std::string& name, const CTxOut bool CClaimTrieCacheBase::haveSupportInQueue(const std::string& name, const CTxOutPoint& outPoint, int& nValidAtHeight) const { - auto query = db << "SELECT validHeight FROM supports WHERE nodeName = ? AND txID = ? AND txN = ? " - "AND validHeight >= ? AND expirationHeight >= validHeight LIMIT 1" + auto query = db << "SELECT activationHeight FROM supports WHERE nodeName = ? AND txID = ? AND txN = ? " + "AND activationHeight >= ? AND expirationHeight >= activationHeight LIMIT 1" << name << outPoint.hash << outPoint.n << nNextHeight; for (auto&& row: query) { row >> nValidAtHeight; @@ -183,7 +191,7 @@ bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::str { if (name.empty()) return false; // to remove a node it must have one or less children and no claims - db << "SELECT COUNT(*) FROM (SELECT 1 FROM claims WHERE nodeName = ?1 AND validHeight < ?2 AND expirationHeight >= ?2 LIMIT 1)" + db << "SELECT COUNT(*) FROM (SELECT 1 FROM claims WHERE nodeName = ?1 AND activationHeight < ?2 AND expirationHeight >= ?2 LIMIT 1)" << name << nNextHeight >> claims; if (claims > 0) return false; // still has claims // we now know it has no claims, but we need to check its children @@ -308,7 +316,7 @@ std::size_t CClaimTrieCacheBase::getTotalNamesInTrie() const { // you could do this select from the nodes table, but you would have to ensure it is not dirty first std::size_t ret; - db << "SELECT COUNT(DISTINCT nodeName) FROM claims WHERE validHeight < ?1 AND expirationHeight >= ?1" + db << "SELECT COUNT(DISTINCT nodeName) FROM claims WHERE activationHeight < ?1 AND expirationHeight >= ?1" << nNextHeight >> ret; return ret; } @@ -316,7 +324,7 @@ std::size_t CClaimTrieCacheBase::getTotalNamesInTrie() const std::size_t CClaimTrieCacheBase::getTotalClaimsInTrie() const { std::size_t ret; - db << "SELECT COUNT(*) FROM claims WHERE validHeight < ?1 AND expirationHeight >= ?1" + db << "SELECT COUNT(*) FROM claims WHERE activationHeight < ?1 AND expirationHeight >= ?1" << nNextHeight >> ret; return ret; } @@ -328,12 +336,12 @@ int64_t CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) "SELECT SUM(amount) FROM (SELECT c.amount as amount, " "(SELECT(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s " "WHERE s.supportedClaimID = c.claimID AND c.nodeName = s.nodeName " - "AND s.validHeight < ?1 AND s.expirationHeight >= ?1) as effective " + "AND s.activationHeight < ?1 AND s.expirationHeight >= ?1) as effective " "ORDER BY effective DESC LIMIT 1) as winner FROM claims c " - "WHERE c.validHeight < ?1 AND c.expirationHeight >= ?1 GROUP BY c.nodeName)" + "WHERE c.activationHeight < ?1 AND c.expirationHeight >= ?1 GROUP BY c.nodeName)" : "SELECT SUM(amount) FROM (SELECT c.amount as amount " - "FROM claims c WHERE c.validHeight < ?1 AND s.expirationHeight >= ?1)"; + "FROM claims c WHERE c.activationHeight < ?1 AND s.expirationHeight >= ?1)"; db << query << nNextHeight >> ret; return ret; @@ -341,8 +349,8 @@ int64_t CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset) const { - auto nextHeight = nNextHeight + heightOffset; auto ret = false; + auto nextHeight = nNextHeight + heightOffset; for (auto&& row: claimHashQuery << nextHeight << name) { row >> claim.outPoint.hash >> claim.outPoint.n >> claim.claimId >> claim.nHeight >> claim.nValidAtHeight >> claim.nAmount >> claim.nEffectiveAmount; @@ -355,15 +363,13 @@ bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& c CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& name) const { - int nLastTakeoverHeight = 0; - db << "SELECT takeoverHeight FROM nodes WHERE name = ?" << name - >> [&nLastTakeoverHeight](int takeoverHeight) { - nLastTakeoverHeight = takeoverHeight; - }; + int nLastTakeoverHeight; + db << "SELECT IFNULL(MAX(height), 0) FROM takeover WHERE name = ?" << name + >> nLastTakeoverHeight; claimEntryType claims; { - auto query = db << "SELECT claimID, txID, txN, blockHeight, validHeight, amount " + auto query = db << "SELECT claimID, txID, txN, blockHeight, activationHeight, amount " "FROM claims WHERE nodeName = ? AND expirationHeight >= ?" << name << nNextHeight; for (auto &&row: query) { @@ -429,7 +435,9 @@ bool CClaimTrieCacheBase::checkConsistency() { // verify that all claims hash to the values on the nodes - auto query = db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes"; + auto query = db << "SELECT n.name, n.hash, " + "(SELECT t.height FROM takeover t WHERE t.name = n.name " + "ORDER BY t.height DESC LIMIT 1) FROM nodes n"; for (auto&& row: query) { std::string name; CUint256 hash; @@ -489,16 +497,21 @@ bool CClaimTrieCacheBase::flush() CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base) : base(base), db(base->dbFile, sharedConfig), transacting(false), - childHashQuery(db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE parent = ? ORDER BY name"), - claimHashQuery(db << "SELECT c.txID, c.txN, c.claimID, c.blockHeight, c.validHeight, c.amount, " - "(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID " - "AND s.nodeName = c.nodeName AND s.validHeight < ?1 AND s.expirationHeight >= ?1) as effectiveAmount " - "FROM claims c WHERE c.nodeName = ?2 AND c.validHeight < ?1 AND c.expirationHeight >= ?1 " + childHashQuery(db << "SELECT n.name, n.hash, (SELECT t.height FROM takeover t " + "WHERE t.name = n.name ORDER BY t.height DESC LIMIT 1) FROM nodes n " + "WHERE n.parent = ? ORDER BY n.name"), + claimHashQuery(db << "SELECT c.txID, c.txN, c.claimID, c.blockHeight, c.activationHeight, c.amount, " + "(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s " + "WHERE s.supportedClaimID = c.claimID AND s.nodeName = c.nodeName " + "AND s.activationHeight < ?1 AND s.expirationHeight >= ?1) as effectiveAmount " + "FROM claims c WHERE c.nodeName = ?2 AND c.activationHeight < ?1 " + "AND c.expirationHeight >= ?1 " "ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN"), - proofClaimQuery("SELECT name, IFNULL(takeoverHeight, 0) FROM nodes WHERE " - "name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL " + proofClaimQuery("SELECT n.name, (SELECT t.height FROM takeover t WHERE t.name = n.name " + "ORDER BY t.height DESC LIMIT 1) FROM nodes n " + "WHERE n.name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL " "SELECT POPS(p) FROM prefix WHERE p != '') SELECT p FROM prefix) " - "ORDER BY name") + "ORDER BY n.name") { assert(base); nNextHeight = base->nNextHeight; @@ -531,14 +544,15 @@ CUint256 CClaimTrieCacheBase::getMerkleHash() ensureTreeStructureIsUpToDate(); CUint256 hash; db << "SELECT hash FROM nodes WHERE name = ''" - >>[&hash](std::unique_ptr rootHash) { + >> [&hash](std::unique_ptr rootHash) { if (rootHash) hash = std::move(*rootHash); }; if (!hash.IsNull()) return hash; assert(transacting); // no data changed but we didn't have the root hash there already? - db << "SELECT name, IFNULL(takeoverHeight, 0) FROM nodes WHERE hash IS NULL ORDER BY SIZE(name) DESC" + db << "SELECT n.name, (SELECT t.height FROM takeover t WHERE t.name = n.name " + "ORDER BY t.height DESC LIMIT 1) FROM nodes n WHERE n.hash IS NULL ORDER BY SIZE(n.name) DESC" >> [this, &hash](const std::string& name, int takeoverHeight) { hash = computeNodeHash(name, takeoverHeight); db << "UPDATE nodes SET hash = ? WHERE name = ?" << hash << name; @@ -548,7 +562,9 @@ CUint256 CClaimTrieCacheBase::getMerkleHash() bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, CUint160& claimId, int& takeoverHeight) const { - auto query = db << "SELECT takeoverHeight, takeoverID FROM nodes WHERE name = ? AND takeoverID IS NOT NULL" << name; + auto query = db << "SELECT t.height, t.claimID FROM takeover t JOIN claims c " + "ON t.claimID = c.claimID AND c.expirationHeight > ?1 " + "WHERE t.name = ?2 ORDER BY t.height DESC LIMIT 1" << nNextHeight << name; auto it = query.begin(); if (it == query.end()) return false; @@ -578,9 +594,9 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const CTxOutPoint& o auto nodeName = adjustNameForValidHeight(name, nValidHeight); auto expires = expirationTime() + nHeight; - db << "INSERT INTO claims(claimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) " - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << claimId << name << nodeName - << outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata; + db << "INSERT INTO claims(claimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, activationHeight, expirationHeight, metadata) " + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + << claimId << name << nodeName << outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << nValidHeight << expires << metadata; if (nValidHeight < nNextHeight) db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName; @@ -599,9 +615,9 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const CTxOutPoint& auto nodeName = adjustNameForValidHeight(name, nValidHeight); auto expires = expirationTime() + nHeight; - db << "INSERT INTO supports(supportedClaimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) " - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << supportedClaimId << name << nodeName - << outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata; + db << "INSERT INTO supports(supportedClaimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, activationHeight, expirationHeight, metadata) " + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + << supportedClaimId << name << nodeName << outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << nValidHeight << expires << metadata; if (nValidHeight < nNextHeight) db << "UPDATE nodes SET hash = NULL WHERE name = ?" << nodeName; @@ -619,7 +635,7 @@ bool CClaimTrieCacheBase::removeClaim(const CUint160& claimId, const CTxOutPoint // we then undo the spend of the previous one by calling addClaim with the original data // in order to maintain the proper takeover height the udpater will need to use our height returned here - auto query = db << "SELECT nodeName, validHeight FROM claims WHERE claimID = ? AND txID = ? AND txN = ? AND expirationHeight >= ?" + auto query = db << "SELECT nodeName, activationHeight FROM claims WHERE claimID = ? AND txID = ? AND txN = ? AND expirationHeight >= ?" << claimId << outPoint.hash << outPoint.n << nNextHeight; auto it = query.begin(); if (it == query.end()) return false; @@ -634,7 +650,7 @@ bool CClaimTrieCacheBase::removeClaim(const CUint160& claimId, const CTxOutPoint // we had a bug in the old code where that situation would force a zero delay on re-add if (true) { // TODO: hard fork this out (which we already tried once but failed) db << "SELECT nodeName FROM claims WHERE nodeName LIKE ?1 " - "AND validHeight < ?2 AND expirationHeight > ?2 ORDER BY nodeName LIMIT 1" + "AND activationHeight < ?2 AND expirationHeight > ?2 ORDER BY nodeName LIMIT 1" << nodeName + '%' << nNextHeight >> [this, &nodeName](const std::string& shortestMatch) { if (shortestMatch != nodeName) @@ -649,7 +665,7 @@ bool CClaimTrieCacheBase::removeSupport(const CTxOutPoint& outPoint, std::string { ensureTransacting(); - auto query = db << "SELECT nodeName, validHeight FROM supports WHERE txID = ? AND txN = ? AND expirationHeight >= ?" + auto query = db << "SELECT nodeName, activationHeight FROM supports WHERE txID = ? AND txN = ? AND expirationHeight >= ?" << outPoint.hash << outPoint.n << nNextHeight; auto it = query.begin(); if (it == query.end()) return false; @@ -1107,9 +1123,7 @@ static const boost::container::flat_map, int> takeov {{658098, "le-temps-nous-glisse-entre-les-doigts"}, 600099}, }; -bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, - takeoverUndoType& takeoverUndo) +bool CClaimTrieCacheBase::incrementBlock() { // the plan: // for every claim and support that becomes active this block set its node hash to null (aka, dirty) @@ -1118,65 +1132,25 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy ensureTransacting(); db << "INSERT INTO nodes(name) SELECT nodeName FROM claims " - "WHERE validHeight = ?1 AND expirationHeight > ?1 " + "WHERE (activationHeight = ?1 AND expirationHeight > ?1) " + "OR expirationHeight = ?1 " + "UNION SELECT nodeName FROM supports " + "WHERE (activationHeight = ?1 AND expirationHeight > ?1) " + "OR expirationHeight = ?1 " "ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight; - db << "UPDATE nodes SET hash = NULL WHERE name IN " - "(SELECT nodeName FROM supports WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight; - - assert(expireUndo.empty()); - { - auto becomingExpired = db << "SELECT txID, txN, nodeName, claimID, validHeight, blockHeight, amount " - "FROM claims WHERE expirationHeight = ?" << nNextHeight; - for (auto &&row: becomingExpired) { - CClaimValue value; - std::string name; - row >> value.outPoint.hash >> value.outPoint.n >> name - >> value.claimId >> value.nValidAtHeight >> value.nHeight >> value.nAmount; - expireUndo.emplace_back(std::move(name), std::move(value)); - } - } - - db << "UPDATE nodes SET hash = NULL WHERE name IN (SELECT nodeName FROM claims WHERE expirationHeight = ?)" << nNextHeight; - - assert(expireSupportUndo.empty()); - { - auto becomingExpired = db << "SELECT txID, txN, nodeName, supportedClaimID, validHeight, blockHeight, amount " - "FROM supports WHERE expirationHeight = ?" << nNextHeight; - for (auto &&row: becomingExpired) { - CSupportValue value; - std::string name; - row >> value.outPoint.hash >> value.outPoint.n >> name - >> value.supportedClaimId >> value.nValidAtHeight >> value.nHeight >> value.nAmount; - expireSupportUndo.emplace_back(std::move(name), std::move(value)); - } - } - - db << "UPDATE nodes SET hash = NULL WHERE name IN (SELECT nodeName FROM supports WHERE expirationHeight = ?)" << nNextHeight; - // takeover handling: - std::vector takeovers; db << "SELECT name FROM nodes WHERE hash IS NULL" - >> [&takeovers](std::string name) { - takeovers.push_back(std::move(name)); - }; - - auto getTakeoverQuery = db << "SELECT IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name = ?"; - auto candidateQuery = db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ? WHERE name = ?"; - - for (const auto& nameWithTakeover : takeovers) { + >> [this](const std::string& nameWithTakeover) { // if somebody activates on this block and they are the new best, then everybody activates on this block CClaimValue candidateValue; auto hasCandidate = getInfoForName(nameWithTakeover, candidateValue, 1); // now that they're all in get the winner: - int existingHeight; - std::unique_ptr existingID; - getTakeoverQuery << nameWithTakeover >> std::tie(existingHeight, existingID); - getTakeoverQuery++; // reset it - - auto hasBeenSetBefore = existingID && !existingID->IsNull(); - auto takeoverHappening = !hasCandidate || (hasBeenSetBefore && *existingID != candidateValue.claimId); - if (takeoverHappening && activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover)) + CUint160 existingID; + int existingHeight = 0; + auto hasBeenSetBefore = getLastTakeoverForName(nameWithTakeover, existingID, existingHeight); + auto takeoverHappening = !hasCandidate || (hasBeenSetBefore && existingID != candidateValue.claimId); + if (takeoverHappening && activateAllFor(nameWithTakeover)) hasCandidate = getInfoForName(nameWithTakeover, candidateValue, 1); // This is a super ugly hack to work around bug in old code. @@ -1189,106 +1163,62 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy logPrint << "Takeover on " << nameWithTakeover << " at " << nNextHeight << ", happening: " << takeoverHappening << ", set before: " << hasBeenSetBefore << Clog::endl; - if (takeoverHappening || !hasBeenSetBefore) { - takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, hasBeenSetBefore ? *existingID : CUint160())); - if (hasCandidate) - candidateQuery << nNextHeight << candidateValue.claimId << nameWithTakeover; - else - candidateQuery << nullptr << nullptr << nameWithTakeover; - candidateQuery++; + if ((takeoverHappening || !hasBeenSetBefore) && hasCandidate) { + db << "INSERT INTO takeover(name, height, claimID) VALUES(?, ?, ?)" + << nameWithTakeover << nNextHeight << candidateValue.claimId; assert(db.rows_modified()); } - } + }; - getTakeoverQuery.used(true); - candidateQuery.used(true); nNextHeight++; return true; } -bool CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo, const std::string& name) +bool CClaimTrieCacheBase::activateAllFor(const std::string& name) { // now that we know a takeover is happening, we bring everybody in: auto ret = false; - { - db << "SELECT txID, txN, validHeight FROM claims WHERE nodeName = ?1 AND validHeight > ?2 AND expirationHeight > ?2" - << name << nNextHeight - >> [this, &insertUndo, &name](CUint256 txId, uint32_t n, int oldValidHeight) { - CTxOutPoint outPoint(std::move(txId), n); - logPrint << "Early activation of claim " << name << ", " << outPoint.ToString() << " at " << nNextHeight << Clog::endl; - insertUndo.emplace_back(name, std::move(outPoint), oldValidHeight); - }; - } - // and then update them all to activate now: - db << "UPDATE claims SET validHeight = ?1 WHERE nodeName = ?2 AND validHeight > ?1 AND expirationHeight > ?1" << nNextHeight << name; + // all to activate now: + db << "UPDATE claims SET activationHeight = ?1 WHERE nodeName = ?2 AND activationHeight > ?1 AND expirationHeight > ?1" << nNextHeight << name; ret |= db.rows_modified() > 0; // then do the same for supports: - { - db << "SELECT txID, txN, validHeight FROM supports WHERE nodeName = ?1 AND validHeight > ?2 AND expirationHeight > ?2" - << name << nNextHeight - >> [this, &insertSupportUndo, &name](CUint256 txId, uint32_t n, int oldValidHeight) { - CTxOutPoint outPoint(std::move(txId), n); - logPrint << "Early activation of support " << name << ", " << outPoint.ToString() << " at " << nNextHeight << Clog::endl; - insertSupportUndo.emplace_back(name, std::move(outPoint), oldValidHeight); - }; - } - // and then update them all to activate now: - db << "UPDATE supports SET validHeight = ?1 WHERE nodeName = ?2 AND validHeight > ?1 AND expirationHeight > ?1" << nNextHeight << name; + db << "UPDATE supports SET activationHeight = ?1 WHERE nodeName = ?2 AND activationHeight > ?1 AND expirationHeight > ?1" << nNextHeight << name; ret |= db.rows_modified() > 0; return ret; } -bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo) +bool CClaimTrieCacheBase::decrementBlock() { ensureTransacting(); nNextHeight--; - auto updateNodes = "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL"; + db << "INSERT INTO nodes(name) SELECT name FROM claims " + "WHERE expirationHeight = ?1 OR activationHeight = ?1 " + "UNION SELECT name FROM supports " + "WHERE expirationHeight = ?1 OR activationHeight = ?1 " + "ON CONFLICT(name) DO UPDATE SET hash = NULL" + << nNextHeight; - // to actually delete the expired items and then restore them here I would have to look up the metadata in the block - // that doesn't sound very fun so we modified the other queries to exclude expired items - for (auto it = expireSupportUndo.crbegin(); it != expireSupportUndo.crend(); ++it) - db << updateNodes << it->first; + db << "UPDATE claims SET activationHeight = validHeight WHERE activationHeight = ?" + << nNextHeight; - for (auto it = expireUndo.crbegin(); it != expireUndo.crend(); ++it) - db << updateNodes << it->first; - - for (auto it = insertSupportUndo.crbegin(); it != insertSupportUndo.crend(); ++it) { - logPrint << "Resetting support valid height to " << it->nValidHeight << " for " << it->name << Clog::endl; - db << "UPDATE supports SET validHeight = ? WHERE txID = ? AND txN = ?" - << it->nValidHeight << it->outPoint.hash << it->outPoint.n; - db << updateNodes << it->name; - } - - for (auto it = insertUndo.crbegin(); it != insertUndo.crend(); ++it) { - logPrint << "Resetting valid height to " << it->nValidHeight << " for " << it->name << Clog::endl; - db << "UPDATE claims SET validHeight = ? WHERE nodeName = ? AND txID = ? AND txN = ?" - << it->nValidHeight << it->name << it->outPoint.hash << it->outPoint.n; - db << updateNodes << it->name; - } + db << "UPDATE supports SET activationHeight = validHeight WHERE activationHeight = ?" + << nNextHeight; return true; } -bool CClaimTrieCacheBase::finalizeDecrement(takeoverUndoType& takeoverUndo) +bool CClaimTrieCacheBase::finalizeDecrement() { db << "UPDATE nodes SET hash = NULL WHERE name IN " - "(SELECT nodeName FROM claims WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight; + "(SELECT nodeName FROM claims WHERE activationHeight = ?1 AND expirationHeight > ?1 " + "UNION SELECT nodeName FROM supports WHERE activationHeight = ?1 AND expirationHeight > ?1 " + "UNION SELECT DISTINCT name FROM takeover WHERE height = ?1)" << nNextHeight; - db << "UPDATE nodes SET hash = NULL WHERE name IN " - "(SELECT nodeName FROM supports WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight; + db << "DELETE FROM takeover WHERE height = ?" << nNextHeight; - auto updateNodes = "UPDATE nodes SET takeoverHeight = ?, takeoverID = ?, hash = NULL WHERE name = ?"; - - for (auto it = takeoverUndo.crbegin(); it != takeoverUndo.crend(); ++it) { - if (it->second.second.IsNull()) - db << updateNodes << nullptr << nullptr << it->first; - else - db << updateNodes << it->second.first << it->second.second << it->first; - } return true; } @@ -1309,7 +1239,6 @@ int CClaimTrieCacheBase::getDelayForName(const std::string& name, const CUint160 removalWorkaround.erase(hit); return 0; } - return found ? std::min((nNextHeight - winningTakeoverHeight) / base->nProportionalDelayFactor, 4032) : 0; } @@ -1370,8 +1299,8 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const CUint16 bool CClaimTrieCacheBase::findNameForClaim(std::vector claim, CClaimValue& value, std::string& name) const { std::reverse(claim.begin(), claim.end()); - auto query = db << "SELECT nodeName, claimId, txID, txN, amount, validHeight, blockHeight " - "FROM claims WHERE SUBSTR(claimID, ?) = ? AND validHeight < ? AND expirationHeight >= ?" + auto query = db << "SELECT nodeName, claimID, txID, txN, amount, activationHeight, blockHeight " + "FROM claims WHERE SUBSTR(claimID, ?) = ? AND activationHeight < ? AND expirationHeight >= ?" << -int(claim.size()) << claim << nNextHeight << nNextHeight; auto hit = false; for (auto&& row: query) { @@ -1385,7 +1314,7 @@ bool CClaimTrieCacheBase::findNameForClaim(std::vector claim, CCl void CClaimTrieCacheBase::getNamesInTrie(std::function callback) const { - db << "SELECT DISTINCT nodeName FROM claims WHERE validHeight < ? AND expirationHeight >= ?" + db << "SELECT DISTINCT nodeName FROM claims WHERE activationHeight < ? AND expirationHeight >= ?" << nNextHeight << nNextHeight >> [&callback](const std::string& name) { callback(name); diff --git a/src/claimtrie/trie.h b/src/claimtrie/trie.h index bcaef79d4..82e569d22 100644 --- a/src/claimtrie/trie.h +++ b/src/claimtrie/trie.h @@ -56,24 +56,6 @@ protected: const int64_t nAllClaimsInMerkleForkHeight; }; -template -using queueEntryType = std::pair; - -#ifdef SWIG_INTERFACE // swig has a problem with using in typedef -using claimUndoPair = std::pair; -using supportUndoPair = std::pair; -using takeoverUndoPair = std::pair>; -#else -using claimUndoPair = queueEntryType; -using supportUndoPair = queueEntryType; -using takeoverUndoPair = queueEntryType>; -#endif - -typedef std::vector claimUndoType; -typedef std::vector supportUndoType; -typedef std::vector insertUndoType; -typedef std::vector takeoverUndoType; - class CClaimTrieCacheBase { public: @@ -104,23 +86,14 @@ public: bool removeClaim(const CUint160& claimId, const CTxOutPoint& outPoint, std::string& nodeName, int& validHeight); bool removeSupport(const CTxOutPoint& outPoint, std::string& nodeName, int& validHeight); - virtual bool incrementBlock(insertUndoType& insertUndo, - claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, - supportUndoType& expireSupportUndo, - takeoverUndoType& takeoverHeightUndo); - - virtual bool decrementBlock(insertUndoType& insertUndo, - claimUndoType& expireUndo, - insertUndoType& insertSupportUndo, - supportUndoType& expireSupportUndo); - - virtual bool getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof); - virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const; + virtual bool incrementBlock(); + virtual bool decrementBlock(); + virtual bool finalizeDecrement(); virtual int expirationTime() const; - virtual bool finalizeDecrement(takeoverUndoType& takeoverHeightUndo); + virtual bool getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof); + virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const; virtual CClaimSupportToName getClaimsForName(const std::string& name) const; virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const; @@ -153,7 +126,7 @@ private: friend struct ClaimTrieChainFixture; friend class CClaimTrieCacheTest; - bool activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo, const std::string& takeover); + bool activateAllFor(const std::string& name); }; #endif // CLAIMTRIE_TRIE_H diff --git a/src/miner.cpp b/src/miner.cpp index 5c45492af..31cd7af2b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -56,12 +56,6 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight) { - insertUndoType dummyInsertUndo; - claimUndoType dummyExpireUndo; - insertUndoType dummyInsertSupportUndo; - supportUndoType dummyExpireSupportUndo; - takeoverUndoType dummyTakeoverUndo; - CUpdateCacheCallbacks callbacks = { .findScriptKey = [&pblock](const COutPoint& point) { for (auto& tx : pblock->vtx) @@ -80,7 +74,7 @@ void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight) if (!tx->IsCoinBase()) UpdateCache(*tx, trieCache, view, nHeight, callbacks); - trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo, dummyTakeoverUndo); + trieCache.incrementBlock(); } BlockAssembler::Options::Options() { diff --git a/src/test/claimtrienormalization_tests.cpp b/src/test/claimtrienormalization_tests.cpp index b393ec615..8f5ade985 100644 --- a/src/test/claimtrienormalization_tests.cpp +++ b/src/test/claimtrienormalization_tests.cpp @@ -222,12 +222,7 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization) BOOST_CHECK(trieCache.getInfoForName(name, nval1)); BOOST_CHECK_EQUAL(nval1.claimId, ClaimIdHash(tx1.GetHash(), 0)); - insertUndoType insertUndo; - claimUndoType expireUndo; - insertUndoType insertSupportUndo; - supportUndoType expireSupportUndo; - takeoverUndoType takeoverUndo; - BOOST_CHECK(trieCache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo)); + BOOST_CHECK(trieCache.incrementBlock()); BOOST_CHECK(trieCache.shouldNormalize()); } @@ -309,18 +304,13 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test) cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height); cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height); cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 1, height); - insertUndoType insertUndo; - claimUndoType expireUndo; - insertUndoType insertSupportUndo; - supportUndoType expireSupportUndo; - takeoverUndoType takeoverUndo; - BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo)); + BOOST_CHECK(cache.incrementBlock()); BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 3U); BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[0].supports.size() == 1U); BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[1].supports.size() == 0U); BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[2].supports.size() == 1U); - BOOST_CHECK(cache.decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)); - BOOST_CHECK(cache.finalizeDecrement(takeoverUndo)); + BOOST_CHECK(cache.decrementBlock()); + BOOST_CHECK(cache.finalizeDecrement()); std::string unused; BOOST_CHECK(cache.removeSupport(COutPoint(sx1.GetHash(), 0), unused, height)); BOOST_CHECK(cache.removeSupport(COutPoint(sx2.GetHash(), 0), unused, height)); diff --git a/src/undo.h b/src/undo.h index e19ec314c..717da7b48 100644 --- a/src/undo.h +++ b/src/undo.h @@ -74,22 +74,12 @@ class CBlockUndo { public: std::vector vtxundo; // for all but the coinbase - insertUndoType insertUndo; // any claims that went from the queue to the trie - claimUndoType expireUndo; // any claims that expired - insertUndoType insertSupportUndo; // any supports that went from the support queue to the support map - supportUndoType expireSupportUndo; // any supports that expired - takeoverUndoType takeoverUndo; ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(vtxundo); - READWRITE(insertUndo); - READWRITE(expireUndo); - READWRITE(insertSupportUndo); - READWRITE(expireSupportUndo); - READWRITE(takeoverUndo); } }; diff --git a/src/validation.cpp b/src/validation.cpp index 83ecdd64e..1659c820a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1507,8 +1507,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI return DISCONNECT_FAILED; } - const bool decremented = trieCache.decrementBlock(blockUndo.insertUndo, blockUndo.expireUndo, blockUndo.insertSupportUndo, blockUndo.expireSupportUndo); - assert(decremented); + assert(trieCache.decrementBlock()); // undo transactions in reverse order for (int i = block.vtx.size() - 1; i >= 0; i--) { @@ -1562,7 +1561,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI // move best block pointer to prevout block view.SetBestBlock(pindex->pprev->GetBlockHash()); - assert(trieCache.finalizeDecrement(blockUndo.takeoverUndo)); + assert(trieCache.finalizeDecrement()); if (!equals(trieCache.getMerkleHash(), pindex->pprev->hashClaimTrie)) { LogPrintf("Hash comparison failure at block %d\n", pindex->nHeight); assert(false); @@ -2035,9 +2034,7 @@ 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. - const auto incremented = trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo, - blockundo.insertSupportUndo, blockundo.expireSupportUndo, blockundo.takeoverUndo); - assert(incremented); + assert(trieCache.incrementBlock()); if (!equals(trieCache.getMerkleHash(), block.hashClaimTrie)) { return state.DoS(100, error("ConnectBlock() : the merkle root of the claim trie does not match "