Browse Source

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.
0.13
Pieter Wuille 10 years ago
parent
commit
02bced1661
  1. 6
      src/coins.cpp

6
src/coins.cpp

@ -106,7 +106,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
assert(!hasModifier); assert(!hasModifier);
hasModifier = true;
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
if (ret.second) { if (ret.second) {
if (!base->GetCoins(txid, ret.first->second.coins)) { 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); 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() CCoinsModifier::~CCoinsModifier()
{ {

Loading…
Cancel
Save