Skip to content

Commit

Permalink
Merge bitcoin#10537: Few Minor per-utxo assert-semantics re-adds and …
Browse files Browse the repository at this point in the history
…tweak

9417d7a Be much more agressive in AccessCoin docs. (Matt Corallo)
f58349c Restore some assert semantics in sigop cost calculations (Matt Corallo)
3533fb4 Return a bool in SpendCoin to restore pre-per-utxo assert semantics (Matt Corallo)
ec1271f Remove useless mapNextTx lookup in CTxMemPool::TrimToSize. (Matt Corallo)

Tree-SHA512: 158a4bce063eac93e1d50709500a10a7cb1fb3271f10ed445d701852fce713e2bf0da3456088e530ab005f194ef4a2adf0c7cb23226b160cecb37a79561f29ca
  • Loading branch information
sipa committed Jun 21, 2017
2 parents efbcf2b + 9417d7a commit b3eb0d6
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 13 deletions.
5 changes: 3 additions & 2 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
if (it == cacheCoins.end()) return;
if (it == cacheCoins.end()) return false;
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
if (moveout) {
*moveout = std::move(it->second.coin);
Expand All @@ -104,6 +104,7 @@ void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
it->second.flags |= CCoinsCacheEntry::DIRTY;
it->second.coin.Clear();
}
return true;
}

static const Coin coinEmpty;
Expand Down
11 changes: 8 additions & 3 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,13 @@ class CCoinsViewCache : public CCoinsViewBacked

/**
* Return a reference to Coin in the cache, or a pruned one if not found. This is
* more efficient than GetCoin. Modifications to other cache entries are
* allowed while accessing the returned pointer.
* more efficient than GetCoin.
*
* Generally, do not hold the reference returned for more than a short scope.
* While the current implementation allows for modifications to the contents
* of the cache while holding the reference, this behavior should not be relied
* on! To be safe, best to not hold the returned reference through any other
* calls to this cache.
*/
const Coin& AccessCoin(const COutPoint &output) const;

Expand All @@ -240,7 +245,7 @@ class CCoinsViewCache : public CCoinsViewBacked
* If no unspent output exists for the passed outpoint, this call
* 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.
Expand Down
8 changes: 6 additions & 2 deletions src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
unsigned int nSigOps = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
const CTxOut &prevout = inputs.AccessCoin(tx.vin[i].prevout).out;
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
assert(!coin.IsSpent());
const CTxOut &prevout = coin.out;
if (prevout.scriptPubKey.IsPayToScriptHash())
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
}
Expand All @@ -146,7 +148,9 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i

for (unsigned int i = 0; i < tx.vin.size(); i++)
{
const CTxOut &prevout = inputs.AccessCoin(tx.vin[i].prevout).out;
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
assert(!coin.IsSpent());
const CTxOut &prevout = coin.out;
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
}
return nSigOps;
Expand Down
4 changes: 1 addition & 3 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1050,9 +1050,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpends
for (const CTransaction& tx : txn) {
for (const CTxIn& txin : tx.vin) {
if (exists(txin.prevout.hash)) continue;
if (!mapNextTx.count(txin.prevout)) {
pvNoSpendsRemaining->push_back(txin.prevout);
}
pvNoSpendsRemaining->push_back(txin.prevout);
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,8 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
txundo.vprevout.reserve(tx.vin.size());
for (const CTxIn &txin : tx.vin) {
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
Expand Down Expand Up @@ -1370,8 +1371,8 @@ static DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex*
if (!tx.vout[o].scriptPubKey.IsUnspendable()) {
COutPoint out(hash, o);
Coin coin;
view.SpendCoin(out, &coin);
if (tx.vout[o] != coin.out) {
bool is_spent = view.SpendCoin(out, &coin);
if (!is_spent || tx.vout[o] != coin.out) {
fClean = false; // transaction output mismatch
}
}
Expand Down

0 comments on commit b3eb0d6

Please sign in to comment.