diff options
| author | Pieter Wuille <[email protected]> | 2015-01-04 17:15:02 +0100 |
|---|---|---|
| committer | Pieter Wuille <[email protected]> | 2015-01-04 17:16:43 +0100 |
| commit | 02bced16615f072b1d9960e7e5027b6eb4f41384 (patch) | |
| tree | 6d01fd4fbce3783a289dfb4d637b0b570398eb0c /src/coins.cpp | |
| parent | Merge pull request #5505 (diff) | |
| download | discoin-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.cpp | 6 |
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() { |