Skip to content

Commit

Permalink
Merge bitcoin#15267: doc: explain AcceptToMemoryPoolWorker's coins_to…
Browse files Browse the repository at this point in the history
…_uncache

5d26205 doc: explain AcceptToMemoryPoolWorker's coins_to_uncache (James O'Beirne)

Pull request description:

  I found ATMPW's `coins_to_uncache` a little hard to understand (see bitcoin#15264). This adds some doc for posterity.

ACKs for commit 5d2620:
  jnewbery:
    ACK 5d26205

Tree-SHA512: 088508fa78012fab8680663c4e30f5cee29768416c2ca8b8b2abc29b6ac7067c5a589674f0254474a7ccc95477889d41719760f5796792bf492f51b3dd499c6c
  • Loading branch information
MarcoFalke authored and vijaydasmp committed Oct 19, 2021
1 parent b042181 commit 459498b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ class CCoinsViewCache : public CCoinsViewBacked
bool HaveInputs(const CTransaction& tx) const;

private:
/**
* @note this is marked const, but may actually append to `cacheCoins`, increasing
* memory usage.
*/
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;
};

Expand Down
16 changes: 16 additions & 0 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,13 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationSt
return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, txdata);
}

/**
* @param[out] coins_to_uncache Return any outpoints which were not previously present in the
* coins cache, but were added as a result of validating the tx
* for mempool acceptance. This allows the caller to optionally
* remove the cache additions if the associated transaction ends
* up being rejected by the mempool.
*/
static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx,
bool* pfMissingInputs, int64_t nAcceptTime, bool bypass_limits,
const CAmount& nAbsurdFee, std::vector<COutPoint>& coins_to_uncache, bool test_accept) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Expand Down Expand Up @@ -733,6 +740,10 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
coins_to_uncache.push_back(txin.prevout);
}

// Note: this call may add txin.prevout to the coins cache
// (pcoinsTip.cacheCoins) by way of FetchCoin(). It should be removed
// later (via coins_to_uncache) if this tx turns out to be invalid.
if (!view.HaveCoin(txin.prevout)) {
// Are inputs missing because we already have the tx?
for (size_t out = 0; out < tx.vout.size(); out++) {
Expand Down Expand Up @@ -927,6 +938,11 @@ static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPo
bool res = AcceptToMemoryPoolWorker(chainparams, pool, state, tx, pfMissingInputs, nAcceptTime, bypass_limits, nAbsurdFee, coins_to_uncache, test_accept);
if (!res || test_accept) {
if(!res) LogPrint(BCLog::MEMPOOL, "%s: %s %s (%s)\n", __func__, tx->GetHash().ToString(), state.GetRejectReason(), state.GetDebugMessage());
// Remove coins that were not present in the coins cache before calling ATMPW;
// this is to prevent memory DoS in case we receive a large number of
// invalid transactions that attempt to overrun the in-memory coins cache
// (`CCoinsViewCache::cacheCoins`).

for (const COutPoint& hashTx : coins_to_uncache)
pcoinsTip->Uncache(hashTx);
}
Expand Down

0 comments on commit 459498b

Please sign in to comment.