aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2015-01-04 17:15:02 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2015-01-07 13:11:54 +0100
commit008138c04a3242b72dc5128ac3585b50ac44e84e (patch)
tree96a36ddacec72f7ac091707424b28c59f2da6080
parent3022e7df2a3f2c6e9869877c189c7e7cea7d7b54 (diff)
downloadbitcoin-008138c04a3242b72dc5128ac3585b50ac44e84e.tar.xz
Bugfix: only track UTXO modification after lookup
Otherwise, if CCoinsViewCache::ModifyCoins throws an exception in between setting hasModifier and constructing the CCoinsModifier, the cache ends up in an inconsistent state, resulting in an assert failure in the next modification. Bug discovered by Wladimir J. van der Laan. Rebased-From: 1c52aad540ec1370db60fd68fc3485413e3cb8e1 Github-Pull: #5597
-rw-r--r--src/coins.cpp6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index c2e802c953..66919da11e 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -106,7 +106,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
assert(!hasModifier);
- hasModifier = true;
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
if (ret.second) {
if (!base->GetCoins(txid, ret.first->second.coins)) {
@@ -247,7 +246,10 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
return tx.ComputePriority(dResult);
}
-CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {}
+CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {
+ assert(!cache.hasModifier);
+ cache.hasModifier = true;
+}
CCoinsModifier::~CCoinsModifier()
{