From 02bced16615f072b1d9960e7e5027b6eb4f41384 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 4 Jan 2015 17:15:02 +0100 Subject: 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. --- src/coins.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/coins.cpp') diff --git a/src/coins.cpp b/src/coins.cpp index bc430c9c7e..4917de625c 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 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() { -- cgit v1.2.3