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:
parent
ec1271f2be
commit
3533fb4d33
3 changed files with 8 additions and 6 deletions
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue