@@ -60,12 +60,7 @@ size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
6060
6161SaltedTxidHasher::SaltedTxidHasher () : k0(GetRand(std::numeric_limits<uint64_t >::max())), k1(GetRand(std::numeric_limits<uint64_t >::max())) {}
6262
63- CCoinsViewCache::CCoinsViewCache (CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false ), cachedCoinsUsage(0 ) { }
64-
65- CCoinsViewCache::~CCoinsViewCache ()
66- {
67- assert (!hasModifier);
68- }
63+ CCoinsViewCache::CCoinsViewCache (CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0 ) { }
6964
7065size_t CCoinsViewCache::DynamicMemoryUsage () const {
7166 return memusage::DynamicUsage (cacheCoins) + cachedCoinsUsage;
@@ -98,62 +93,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
9893 return false ;
9994}
10095
101- CCoinsModifier CCoinsViewCache::ModifyCoins (const uint256 &txid) {
102- assert (!hasModifier);
103- std::pair<CCoinsMap::iterator, bool > ret = cacheCoins.insert (std::make_pair (txid, CCoinsCacheEntry ()));
104- size_t cachedCoinUsage = 0 ;
105- if (ret.second ) {
106- if (!base->GetCoins (txid, ret.first ->second .coins )) {
107- // The parent view does not have this entry; mark it as fresh.
108- ret.first ->second .coins .Clear ();
109- ret.first ->second .flags = CCoinsCacheEntry::FRESH;
110- } else if (ret.first ->second .coins .IsPruned ()) {
111- // The parent view only has a pruned entry for this; mark it as fresh.
112- ret.first ->second .flags = CCoinsCacheEntry::FRESH;
113- }
114- } else {
115- cachedCoinUsage = ret.first ->second .coins .DynamicMemoryUsage ();
116- }
117- // Assume that whenever ModifyCoins is called, the entry will be modified.
118- ret.first ->second .flags |= CCoinsCacheEntry::DIRTY;
119- return CCoinsModifier (*this , ret.first , cachedCoinUsage);
120- }
121-
122- /* ModifyNewCoins allows for faster coin modification when creating the new
123- * outputs from a transaction. It assumes that BIP 30 (no duplicate txids)
124- * applies and has already been tested for (or the test is not required due to
125- * BIP 34, height in coinbase). If we can assume BIP 30 then we know that any
126- * non-coinbase transaction we are adding to the UTXO must not already exist in
127- * the utxo unless it is fully spent. Thus we can check only if it exists DIRTY
128- * at the current level of the cache, in which case it is not safe to mark it
129- * FRESH (b/c then its spentness still needs to flushed). If it's not dirty and
130- * doesn't exist or is pruned in the current cache, we know it either doesn't
131- * exist or is pruned in parent caches, which is the definition of FRESH. The
132- * exception to this is the two historical violations of BIP 30 in the chain,
133- * both of which were coinbases. We do not mark these fresh so we we can ensure
134- * that they will still be properly overwritten when spent.
135- */
136- CCoinsModifier CCoinsViewCache::ModifyNewCoins (const uint256 &txid, bool coinbase) {
137- assert (!hasModifier);
138- std::pair<CCoinsMap::iterator, bool > ret = cacheCoins.insert (std::make_pair (txid, CCoinsCacheEntry ()));
139- if (!coinbase) {
140- // New coins must not already exist.
141- if (!ret.first ->second .coins .IsPruned ())
142- throw std::logic_error (" ModifyNewCoins should not find pre-existing coins on a non-coinbase unless they are pruned!" );
143-
144- if (!(ret.first ->second .flags & CCoinsCacheEntry::DIRTY)) {
145- // If the coin is known to be pruned (have no unspent outputs) in
146- // the current view and the cache entry is not dirty, we know the
147- // coin also must be pruned in the parent view as well, so it is safe
148- // to mark this fresh.
149- ret.first ->second .flags |= CCoinsCacheEntry::FRESH;
150- }
151- }
152- ret.first ->second .coins .Clear ();
153- ret.first ->second .flags |= CCoinsCacheEntry::DIRTY;
154- return CCoinsModifier (*this , ret.first , 0 );
155- }
156-
15796void CCoinsViewCache::AddCoin (const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) {
15897 assert (!coin.IsPruned ());
15998 if (coin.out .scriptPubKey .IsUnspendable ()) return ;
@@ -257,7 +196,6 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
257196}
258197
259198bool CCoinsViewCache::BatchWrite (CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
260- assert (!hasModifier);
261199 for (CCoinsMap::iterator it = mapCoins.begin (); it != mapCoins.end ();) {
262200 if (it->second .flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
263201 CCoinsMap::iterator itUs = cacheCoins.find (it->first );
@@ -366,25 +304,6 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
366304 return true ;
367305}
368306
369- CCoinsModifier::CCoinsModifier (CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage) : cache(cache_), it(it_), cachedCoinUsage(usage) {
370- assert (!cache.hasModifier );
371- cache.hasModifier = true ;
372- }
373-
374- CCoinsModifier::~CCoinsModifier ()
375- {
376- assert (cache.hasModifier );
377- cache.hasModifier = false ;
378- it->second .coins .Cleanup ();
379- cache.cachedCoinsUsage -= cachedCoinUsage; // Subtract the old usage
380- if ((it->second .flags & CCoinsCacheEntry::FRESH) && it->second .coins .IsPruned ()) {
381- cache.cacheCoins .erase (it);
382- } else {
383- // If the coin still exists after the modification, add the new usage
384- cache.cachedCoinsUsage += it->second .coins .DynamicMemoryUsage ();
385- }
386- }
387-
388307CCoinsViewCursor::~CCoinsViewCursor ()
389308{
390309}
0 commit comments