Skip to content

Commit b3eb0d6

Browse files
committed
Merge #10537: Few Minor per-utxo assert-semantics re-adds and 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
2 parents efbcf2b + 9417d7a commit b3eb0d6

File tree

5 files changed

+22
-13
lines changed

5 files changed

+22
-13
lines changed

src/coins.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) {
9191
}
9292
}
9393

94-
void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
94+
bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
9595
CCoinsMap::iterator it = FetchCoin(outpoint);
96-
if (it == cacheCoins.end()) return;
96+
if (it == cacheCoins.end()) return false;
9797
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
9898
if (moveout) {
9999
*moveout = std::move(it->second.coin);
@@ -104,6 +104,7 @@ void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
104104
it->second.flags |= CCoinsCacheEntry::DIRTY;
105105
it->second.coin.Clear();
106106
}
107+
return true;
107108
}
108109

109110
static const Coin coinEmpty;

src/coins.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,13 @@ class CCoinsViewCache : public CCoinsViewBacked
224224

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

@@ -240,7 +245,7 @@ class CCoinsViewCache : public CCoinsViewBacked
240245
* If no unspent output exists for the passed outpoint, this call
241246
* has no effect.
242247
*/
243-
void SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);
248+
bool SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);
244249

245250
/**
246251
* Push the modifications applied to this cache to its base.

src/consensus/tx_verify.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
126126
unsigned int nSigOps = 0;
127127
for (unsigned int i = 0; i < tx.vin.size(); i++)
128128
{
129-
const CTxOut &prevout = inputs.AccessCoin(tx.vin[i].prevout).out;
129+
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
130+
assert(!coin.IsSpent());
131+
const CTxOut &prevout = coin.out;
130132
if (prevout.scriptPubKey.IsPayToScriptHash())
131133
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
132134
}
@@ -146,7 +148,9 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
146148

147149
for (unsigned int i = 0; i < tx.vin.size(); i++)
148150
{
149-
const CTxOut &prevout = inputs.AccessCoin(tx.vin[i].prevout).out;
151+
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
152+
assert(!coin.IsSpent());
153+
const CTxOut &prevout = coin.out;
150154
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
151155
}
152156
return nSigOps;

src/txmempool.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,9 +1050,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpends
10501050
for (const CTransaction& tx : txn) {
10511051
for (const CTxIn& txin : tx.vin) {
10521052
if (exists(txin.prevout.hash)) continue;
1053-
if (!mapNextTx.count(txin.prevout)) {
1054-
pvNoSpendsRemaining->push_back(txin.prevout);
1055-
}
1053+
pvNoSpendsRemaining->push_back(txin.prevout);
10561054
}
10571055
}
10581056
}

src/validation.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,8 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
11251125
txundo.vprevout.reserve(tx.vin.size());
11261126
for (const CTxIn &txin : tx.vin) {
11271127
txundo.vprevout.emplace_back();
1128-
inputs.SpendCoin(txin.prevout, &txundo.vprevout.back());
1128+
bool is_spent = inputs.SpendCoin(txin.prevout, &txundo.vprevout.back());
1129+
assert(is_spent);
11291130
}
11301131
}
11311132
// add outputs
@@ -1370,8 +1371,8 @@ static DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex*
13701371
if (!tx.vout[o].scriptPubKey.IsUnspendable()) {
13711372
COutPoint out(hash, o);
13721373
Coin coin;
1373-
view.SpendCoin(out, &coin);
1374-
if (tx.vout[o] != coin.out) {
1374+
bool is_spent = view.SpendCoin(out, &coin);
1375+
if (!is_spent || tx.vout[o] != coin.out) {
13751376
fClean = false; // transaction output mismatch
13761377
}
13771378
}

0 commit comments

Comments
 (0)