aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2017-04-25 11:29:36 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2017-06-01 12:43:16 -0700
commit05293f3cb75ad08ca23cba8e795e27d4d5e4d690 (patch)
tree20109e5437f7ce1e2a111f0d8a20e0e72204b249
parent961e4839793f8b4ad37d29672faf1695ff6ec03a (diff)
Remove ModifyCoins/ModifyNewCoins
-rw-r--r--src/coins.cpp83
-rw-r--r--src/coins.h47
2 files changed, 1 insertions, 129 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index 3ac46d0806..8b2f148379 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -60,12 +60,7 @@ size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
-CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { }
-
-CCoinsViewCache::~CCoinsViewCache()
-{
- assert(!hasModifier);
-}
+CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) { }
size_t CCoinsViewCache::DynamicMemoryUsage() const {
return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
@@ -98,62 +93,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
return false;
}
-CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
- assert(!hasModifier);
- std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
- size_t cachedCoinUsage = 0;
- if (ret.second) {
- if (!base->GetCoins(txid, ret.first->second.coins)) {
- // The parent view does not have this entry; mark it as fresh.
- ret.first->second.coins.Clear();
- ret.first->second.flags = CCoinsCacheEntry::FRESH;
- } else if (ret.first->second.coins.IsPruned()) {
- // The parent view only has a pruned entry for this; mark it as fresh.
- ret.first->second.flags = CCoinsCacheEntry::FRESH;
- }
- } else {
- cachedCoinUsage = ret.first->second.coins.DynamicMemoryUsage();
- }
- // Assume that whenever ModifyCoins is called, the entry will be modified.
- ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
- return CCoinsModifier(*this, ret.first, cachedCoinUsage);
-}
-
-/* ModifyNewCoins allows for faster coin modification when creating the new
- * outputs from a transaction. It assumes that BIP 30 (no duplicate txids)
- * applies and has already been tested for (or the test is not required due to
- * BIP 34, height in coinbase). If we can assume BIP 30 then we know that any
- * non-coinbase transaction we are adding to the UTXO must not already exist in
- * the utxo unless it is fully spent. Thus we can check only if it exists DIRTY
- * at the current level of the cache, in which case it is not safe to mark it
- * FRESH (b/c then its spentness still needs to flushed). If it's not dirty and
- * doesn't exist or is pruned in the current cache, we know it either doesn't
- * exist or is pruned in parent caches, which is the definition of FRESH. The
- * exception to this is the two historical violations of BIP 30 in the chain,
- * both of which were coinbases. We do not mark these fresh so we we can ensure
- * that they will still be properly overwritten when spent.
- */
-CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid, bool coinbase) {
- assert(!hasModifier);
- std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
- if (!coinbase) {
- // New coins must not already exist.
- if (!ret.first->second.coins.IsPruned())
- throw std::logic_error("ModifyNewCoins should not find pre-existing coins on a non-coinbase unless they are pruned!");
-
- if (!(ret.first->second.flags & CCoinsCacheEntry::DIRTY)) {
- // If the coin is known to be pruned (have no unspent outputs) in
- // the current view and the cache entry is not dirty, we know the
- // coin also must be pruned in the parent view as well, so it is safe
- // to mark this fresh.
- ret.first->second.flags |= CCoinsCacheEntry::FRESH;
- }
- }
- ret.first->second.coins.Clear();
- ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
- return CCoinsModifier(*this, ret.first, 0);
-}
-
void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) {
assert(!coin.IsPruned());
if (coin.out.scriptPubKey.IsUnspendable()) return;
@@ -257,7 +196,6 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
}
bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
- assert(!hasModifier);
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
CCoinsMap::iterator itUs = cacheCoins.find(it->first);
@@ -366,25 +304,6 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
return true;
}
-CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage) : cache(cache_), it(it_), cachedCoinUsage(usage) {
- assert(!cache.hasModifier);
- cache.hasModifier = true;
-}
-
-CCoinsModifier::~CCoinsModifier()
-{
- assert(cache.hasModifier);
- cache.hasModifier = false;
- it->second.coins.Cleanup();
- cache.cachedCoinsUsage -= cachedCoinUsage; // Subtract the old usage
- if ((it->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
- cache.cacheCoins.erase(it);
- } else {
- // If the coin still exists after the modification, add the new usage
- cache.cachedCoinsUsage += it->second.coins.DynamicMemoryUsage();
- }
-}
-
CCoinsViewCursor::~CCoinsViewCursor()
{
}
diff --git a/src/coins.h b/src/coins.h
index 5879530f95..fcf7c47a56 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -405,36 +405,10 @@ public:
};
-class CCoinsViewCache;
-
-/**
- * A reference to a mutable cache entry. Encapsulating it allows us to run
- * cleanup code after the modification is finished, and keeping track of
- * concurrent modifications.
- */
-class CCoinsModifier
-{
-private:
- CCoinsViewCache& cache;
- CCoinsMap::iterator it;
- size_t cachedCoinUsage; // Cached memory usage of the CCoins object before modification
- CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage);
-
-public:
- CCoins* operator->() { return &it->second.coins; }
- CCoins& operator*() { return it->second.coins; }
- ~CCoinsModifier();
- friend class CCoinsViewCache;
-};
-
/** CCoinsView that adds a memory cache for transactions to another CCoinsView */
class CCoinsViewCache : public CCoinsViewBacked
{
protected:
- /* Whether this cache has an active modifier. */
- bool hasModifier;
-
-
/**
* Make mutable so that we can "fill the cache" even from Get-methods
* declared as "const".
@@ -447,7 +421,6 @@ protected:
public:
CCoinsViewCache(CCoinsView *baseIn);
- ~CCoinsViewCache();
// Standard CCoinsView methods
bool GetCoins(const uint256 &txid, CCoins &coins) const;
@@ -480,24 +453,6 @@ public:
const Coin AccessCoin(const COutPoint &output) const;
/**
- * Return a modifiable reference to a CCoins. If no entry with the given
- * txid exists, a new one is created. Simultaneous modifications are not
- * allowed.
- */
- CCoinsModifier ModifyCoins(const uint256 &txid);
-
- /**
- * Return a modifiable reference to a CCoins. Assumes that no entry with the given
- * txid exists and creates a new one. This saves a database access in the case where
- * the coins were to be wiped out by FromTx anyway. This should not be called with
- * the 2 historical coinbase duplicate pairs because the new coins are marked fresh, and
- * in the event the duplicate coinbase was spent before a flush, the now pruned coins
- * would not properly overwrite the first coinbase of the pair. Simultaneous modifications
- * are not allowed.
- */
- CCoinsModifier ModifyNewCoins(const uint256 &txid, bool coinbase);
-
- /**
* Add a coin. Set potential_overwrite to true if a non-pruned version may
* already exist.
*/
@@ -544,8 +499,6 @@ public:
const CTxOut &GetOutputFor(const CTxIn& input) const;
- friend class CCoinsModifier;
-
private:
CCoinsMap::iterator FetchCoins(const uint256 &txid) const;