Remove ModifyCoins/ModifyNewCoins
This commit is contained in:
parent
961e483979
commit
05293f3cb7
2 changed files with 1 additions and 129 deletions
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
|
47
src/coins.h
47
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;
|
||||
|
@ -479,24 +452,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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue