aboutsummaryrefslogtreecommitdiff
path: root/src/coins.cpp
diff options
context:
space:
mode:
authorPieter Wuille <[email protected]>2015-01-04 17:15:02 +0100
committerPieter Wuille <[email protected]>2015-01-04 17:16:43 +0100
commit02bced16615f072b1d9960e7e5027b6eb4f41384 (patch)
tree6d01fd4fbce3783a289dfb4d637b0b570398eb0c /src/coins.cpp
parentMerge pull request #5505 (diff)
downloaddiscoin-02bced16615f072b1d9960e7e5027b6eb4f41384.tar.xz
discoin-02bced16615f072b1d9960e7e5027b6eb4f41384.zip
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.
Diffstat (limited to 'src/coins.cpp')
-rw-r--r--src/coins.cpp6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index bc430c9c7..4917de625 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()
{