aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/coins.cpp9
-rw-r--r--src/coins.h11
-rw-r--r--src/main.cpp13
3 files changed, 30 insertions, 3 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index f02949de53..96b336ce77 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -117,6 +117,15 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
return CCoinsModifier(*this, ret.first, cachedCoinUsage);
}
+CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid) {
+ 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;
+ ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
+ return CCoinsModifier(*this, ret.first, 0);
+}
+
const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const {
CCoinsMap::const_iterator it = FetchCoins(txid);
if (it == cacheCoins.end()) {
diff --git a/src/coins.h b/src/coins.h
index bf4a777b8a..3b45cb0a34 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -420,6 +420,17 @@ public:
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);
+
+ /**
* Push the modifications applied to this cache to its base.
* Failure to call this method before destruction will cause the changes to be forgotten.
* If false is returned, the state of this cache (and its backing view) will be undefined.
diff --git a/src/main.cpp b/src/main.cpp
index 26a22ae6fd..270b4c063a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1285,10 +1285,17 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
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.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
}
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight)