aboutsummaryrefslogtreecommitdiff
path: root/src/coins.cpp
diff options
context:
space:
mode:
authorAlex Morcos <morcos@chaincode.com>2015-11-12 16:57:03 -0500
committerAlex Morcos <morcos@chaincode.com>2015-11-18 12:16:40 -0500
commit8504867b146014c99c6acb180020a1369069c761 (patch)
treeeb651ea7ab069c76e1252d8617c260250f5edc5d /src/coins.cpp
parent072e2f864445bc6ef3b390255f08c9e8bec2ea94 (diff)
downloadbitcoin-8504867b146014c99c6acb180020a1369069c761.tar.xz
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.
Diffstat (limited to 'src/coins.cpp')
-rw-r--r--src/coins.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index f0ea5c0459..660181b0c4 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -117,11 +117,17 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
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);
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
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;
return CCoinsModifier(*this, ret.first, 0);
}