Return a bool in SpendCoin to restore pre-per-utxo assert semantics

Since its free to do so, assert that Spends succeeded when we expect
them to.
This commit is contained in:
Matt Corallo 2017-06-05 11:50:47 -04:00
parent ec1271f2be
commit 3533fb4d33
3 changed files with 8 additions and 6 deletions

View File

@ -91,9 +91,9 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) {
} }
} }
void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) { bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
CCoinsMap::iterator it = FetchCoin(outpoint); CCoinsMap::iterator it = FetchCoin(outpoint);
if (it == cacheCoins.end()) return; if (it == cacheCoins.end()) return false;
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage(); cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
if (moveout) { if (moveout) {
*moveout = std::move(it->second.coin); *moveout = std::move(it->second.coin);
@ -104,6 +104,7 @@ void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
it->second.flags |= CCoinsCacheEntry::DIRTY; it->second.flags |= CCoinsCacheEntry::DIRTY;
it->second.coin.Clear(); it->second.coin.Clear();
} }
return true;
} }
static const Coin coinEmpty; static const Coin coinEmpty;

View File

@ -238,7 +238,7 @@ public:
* If no unspent output exists for the passed outpoint, this call * If no unspent output exists for the passed outpoint, this call
* has no effect. * has no effect.
*/ */
void SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr); bool SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);
/** /**
* Push the modifications applied to this cache to its base. * Push the modifications applied to this cache to its base.

View File

@ -1118,7 +1118,8 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
txundo.vprevout.reserve(tx.vin.size()); txundo.vprevout.reserve(tx.vin.size());
BOOST_FOREACH(const CTxIn &txin, tx.vin) { BOOST_FOREACH(const CTxIn &txin, tx.vin) {
txundo.vprevout.emplace_back(); txundo.vprevout.emplace_back();
inputs.SpendCoin(txin.prevout, &txundo.vprevout.back()); bool is_spent = inputs.SpendCoin(txin.prevout, &txundo.vprevout.back());
assert(is_spent);
} }
} }
// add outputs // add outputs
@ -1358,8 +1359,8 @@ static DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex*
if (!tx.vout[o].scriptPubKey.IsUnspendable()) { if (!tx.vout[o].scriptPubKey.IsUnspendable()) {
COutPoint out(hash, o); COutPoint out(hash, o);
Coin coin; Coin coin;
view.SpendCoin(out, &coin); bool is_spent = view.SpendCoin(out, &coin);
if (tx.vout[o] != coin.out) { if (!is_spent || tx.vout[o] != coin.out) {
fClean = false; // transaction output mismatch fClean = false; // transaction output mismatch
} }
} }