Skip to content

Commit

Permalink
Bugfix: only track UTXO modification after lookup
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sipa committed Jan 4, 2015
1 parent a99ef7d commit 02bced1
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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()
{
Expand Down

0 comments on commit 02bced1

Please sign in to comment.