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 318 : bool CCoinsViewDB::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { 14 318 : if (rt == SaplingMerkleTree::empty_root()) { 15 490 : SaplingMerkleTree new_tree; 16 245 : tree = new_tree; 17 245 : 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 148 : bool CCoinsViewDB::GetNullifier(const uint256 &nf) const { 26 148 : bool spent = false; 27 148 : return db.Read(std::make_pair(DB_SAPLING_NULLIFIER, nf), spent); 28 : } 29 : 30 335 : uint256 CCoinsViewDB::GetBestAnchor() const { 31 335 : uint256 hashBestAnchor; 32 335 : if (!db.Read(DB_BEST_SAPLING_ANCHOR, hashBestAnchor)) 33 122 : return SaplingMerkleTree::empty_root(); 34 213 : return hashBestAnchor; 35 : } 36 : 37 634 : void BatchWriteNullifiers(CDBBatch& batch, CNullifiersMap& mapToUse, const char& dbChar) 38 : { 39 634 : size_t count = 0; 40 634 : size_t changed = 0; 41 781 : for (CNullifiersMap::iterator it = mapToUse.begin(); it != mapToUse.end();) { 42 147 : if (it->second.flags & CNullifiersCacheEntry::DIRTY) { 43 144 : if (!it->second.entered) 44 0 : batch.Erase(std::make_pair(dbChar, it->first)); 45 : else 46 144 : batch.Write(std::make_pair(dbChar, it->first), true); 47 144 : changed++; 48 : } 49 147 : count++; 50 147 : CNullifiersMap::iterator itOld = it++; 51 147 : mapToUse.erase(itOld); 52 : } 53 634 : LogPrint(BCLog::COINDB, "Committed %u changed nullifiers (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); 54 634 : } 55 : 56 : template<typename Map, typename MapIterator, typename MapEntry, typename Tree> 57 634 : void BatchWriteAnchors(CDBBatch& batch, Map& mapToUse, const char& dbChar) 58 : { 59 634 : size_t count = 0; 60 634 : size_t changed = 0; 61 1119 : for (MapIterator it = mapToUse.begin(); it != mapToUse.end();) { 62 485 : if (it->second.flags & MapEntry::DIRTY) { 63 220 : if (!it->second.entered) 64 1 : batch.Erase(std::make_pair(dbChar, it->first)); 65 : else { 66 219 : if (it->first != Tree::empty_root()) { 67 219 : batch.Write(std::make_pair(dbChar, it->first), it->second.tree); 68 : } 69 : } 70 220 : changed++; 71 : } 72 485 : count++; 73 485 : MapIterator itOld = it++; 74 485 : mapToUse.erase(itOld); 75 : } 76 634 : LogPrint(BCLog::COINDB, "Committed %u changed sapling anchors (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); 77 634 : } 78 : 79 634 : bool CCoinsViewDB::BatchWriteSapling(const uint256& hashSaplingAnchor, 80 : CAnchorsSaplingMap& mapSaplingAnchors, 81 : CNullifiersMap& mapSaplingNullifiers, 82 : CDBBatch& batch) { 83 : 84 634 : ::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry, SaplingMerkleTree>(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR); 85 634 : ::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER); 86 1268 : if (!hashSaplingAnchor.IsNull()) 87 381 : batch.Write(DB_BEST_SAPLING_ANCHOR, hashSaplingAnchor); 88 634 : return true; 89 : }