Line data Source code
1 : // Copyright (c) 2016-2020 The PIVX Core developers 2 : // Distributed under the MIT/X11 software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #include "txdb.h" 6 : 7 : // Db keys 8 : static const char DB_SAPLING_ANCHOR = 'Z'; 9 : static const char DB_SAPLING_NULLIFIER = 'S'; 10 : static const char DB_BEST_SAPLING_ANCHOR = 'z'; 11 : 12 : // Sapling 13 417 : bool CCoinsViewDB::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { 14 417 : if (rt == SaplingMerkleTree::empty_root()) { 15 688 : SaplingMerkleTree new_tree; 16 344 : tree = new_tree; 17 344 : return true; 18 : } 19 : 20 73 : bool read = db.Read(std::make_pair(DB_SAPLING_ANCHOR, rt), tree); 21 : 22 73 : return read; 23 : } 24 : 25 153 : bool CCoinsViewDB::GetNullifier(const uint256 &nf) const { 26 153 : bool spent = false; 27 153 : return db.Read(std::make_pair(DB_SAPLING_NULLIFIER, nf), spent); 28 : } 29 : 30 395 : uint256 CCoinsViewDB::GetBestAnchor() const { 31 395 : uint256 hashBestAnchor; 32 395 : if (!db.Read(DB_BEST_SAPLING_ANCHOR, hashBestAnchor)) 33 176 : return SaplingMerkleTree::empty_root(); 34 219 : return hashBestAnchor; 35 : } 36 : 37 805 : void BatchWriteNullifiers(CDBBatch& batch, CNullifiersMap& mapToUse, const char& dbChar) 38 : { 39 805 : size_t count = 0; 40 805 : size_t changed = 0; 41 957 : for (CNullifiersMap::iterator it = mapToUse.begin(); it != mapToUse.end();) { 42 152 : if (it->second.flags & CNullifiersCacheEntry::DIRTY) { 43 148 : if (!it->second.entered) 44 0 : batch.Erase(std::make_pair(dbChar, it->first)); 45 : else 46 148 : batch.Write(std::make_pair(dbChar, it->first), true); 47 148 : changed++; 48 : } 49 152 : count++; 50 152 : CNullifiersMap::iterator itOld = it++; 51 152 : mapToUse.erase(itOld); 52 : } 53 805 : LogPrint(BCLog::COINDB, "Committed %u changed nullifiers (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); 54 805 : } 55 : 56 : template<typename Map, typename MapIterator, typename MapEntry, typename Tree> 57 805 : void BatchWriteAnchors(CDBBatch& batch, Map& mapToUse, const char& dbChar) 58 : { 59 805 : size_t count = 0; 60 805 : size_t changed = 0; 61 1387 : for (MapIterator it = mapToUse.begin(); it != mapToUse.end();) { 62 582 : if (it->second.flags & MapEntry::DIRTY) { 63 218 : if (!it->second.entered) 64 1 : batch.Erase(std::make_pair(dbChar, it->first)); 65 : else { 66 217 : if (it->first != Tree::empty_root()) { 67 217 : batch.Write(std::make_pair(dbChar, it->first), it->second.tree); 68 : } 69 : } 70 218 : changed++; 71 : } 72 582 : count++; 73 582 : MapIterator itOld = it++; 74 582 : mapToUse.erase(itOld); 75 : } 76 805 : LogPrint(BCLog::COINDB, "Committed %u changed sapling anchors (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); 77 805 : } 78 : 79 805 : bool CCoinsViewDB::BatchWriteSapling(const uint256& hashSaplingAnchor, 80 : CAnchorsSaplingMap& mapSaplingAnchors, 81 : CNullifiersMap& mapSaplingNullifiers, 82 : CDBBatch& batch) { 83 : 84 805 : ::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry, SaplingMerkleTree>(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR); 85 805 : ::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER); 86 1610 : if (!hashSaplingAnchor.IsNull()) 87 540 : batch.Write(DB_BEST_SAPLING_ANCHOR, hashSaplingAnchor); 88 805 : return true; 89 : }