Browse Source

Save the last unnecessary database read

It's possible coins with the same hash exist when you create a duplicate coinbase, so previously we were reading from the database to make sure we had the old coins cached so if we were to spend the new ones, the old ones would also be spent.  This pull instead just marks the new coins as not fresh if they are from a coinbase, so if they are spent they will be written all the way down to the database anyway overwriting any duplicates.
0.13
Alex Morcos 9 years ago
parent
commit
8504867b14
  1. 10
      src/coins.cpp
  2. 2
      src/coins.h
  3. 12
      src/main.cpp

10
src/coins.cpp

@ -117,11 +117,17 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
return CCoinsModifier(*this, ret.first, cachedCoinUsage); return CCoinsModifier(*this, ret.first, cachedCoinUsage);
} }
CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid) { // ModifyNewCoins has to know whether the new outputs its creating are for a
// coinbase or not. If they are for a coinbase, it can not mark them as fresh.
// This is to ensure that the historical duplicate coinbases before BIP30 was
// in effect will still be properly overwritten when spent.
CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid, bool coinbase) {
assert(!hasModifier); assert(!hasModifier);
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
ret.first->second.coins.Clear(); ret.first->second.coins.Clear();
ret.first->second.flags = CCoinsCacheEntry::FRESH; if (!coinbase) {
ret.first->second.flags = CCoinsCacheEntry::FRESH;
}
ret.first->second.flags |= CCoinsCacheEntry::DIRTY; ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
return CCoinsModifier(*this, ret.first, 0); return CCoinsModifier(*this, ret.first, 0);
} }

2
src/coins.h

@ -428,7 +428,7 @@ public:
* would not properly overwrite the first coinbase of the pair. Simultaneous modifications * would not properly overwrite the first coinbase of the pair. Simultaneous modifications
* are not allowed. * are not allowed.
*/ */
CCoinsModifier ModifyNewCoins(const uint256 &txid); CCoinsModifier ModifyNewCoins(const uint256 &txid, bool coinbase);
/** /**
* Push the modifications applied to this cache to its base. * Push the modifications applied to this cache to its base.

12
src/main.cpp

@ -1310,17 +1310,9 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
undo.nVersion = coins->nVersion; undo.nVersion = coins->nVersion;
} }
} }
// add outputs
inputs.ModifyNewCoins(tx.GetHash())->FromTx(tx, nHeight);
}
else {
// add outputs for coinbase tx
// In this case call the full ModifyCoins which will do a database
// lookup to be sure the coins do not already exist otherwise we do not
// know whether to mark them fresh or not. We want the duplicate coinbases
// before BIP30 to still be properly overwritten.
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
} }
// add outputs
inputs.ModifyNewCoins(tx.GetHash(), tx.IsCoinBase())->FromTx(tx, nHeight);
} }
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight)

Loading…
Cancel
Save