Browse Source

scripted-diff: various renames for per-utxo consistency

Thanks to John Newberry for pointing these out.

-BEGIN VERIFY SCRIPT-
sed -i 's/\<GetCoins\>/GetCoin/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<HaveCoins\>/HaveCoin/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<HaveCoinsInCache\>/HaveCoinInCache/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<IsPruned\>/IsSpent/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<FetchCoins\>/FetchCoin/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<CoinsEntry\>/CoinEntry/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<vHashTxnToUncache\>/coins_to_uncache/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<vHashTxToUncache\>/coins_to_uncache/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<fHadTxInCache\>/had_coin_in_cache/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<coinbaseids\>/coinbase_coins/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<disconnectedids\>/disconnected_coins/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<duplicateids\>/duplicate_coins/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
sed -i 's/\<oldcoins\>/old_coin/g' src/test/coins_tests.cpp
sed -i 's/\<origcoins\>/orig_coin/g' src/*.cpp src/*.h src/*/*.cpp src/*/*.h
-END VERIFY SCRIPT-
pull/1/head
Pieter Wuille 6 years ago
parent
commit
589827975f
  1. 4
      src/bitcoin-tx.cpp
  2. 44
      src/coins.cpp
  3. 24
      src/coins.h
  4. 2
      src/consensus/tx_verify.cpp
  5. 4
      src/init.cpp
  6. 4
      src/net_processing.cpp
  7. 2
      src/qt/transactiondesc.cpp
  8. 2
      src/rest.cpp
  9. 4
      src/rpc/blockchain.cpp
  10. 8
      src/rpc/rawtransaction.cpp
  11. 90
      src/test/coins_tests.cpp
  12. 20
      src/txdb.cpp
  13. 4
      src/txdb.h
  14. 14
      src/txmempool.cpp
  15. 4
      src/txmempool.h
  16. 34
      src/validation.cpp

4
src/bitcoin-tx.cpp

@ -562,7 +562,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) @@ -562,7 +562,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
{
const Coin& coin = view.AccessCoin(out);
if (!coin.IsPruned() && coin.out.scriptPubKey != scriptPubKey) {
if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
std::string err("Previous output scriptPubKey mismatch:\n");
err = err + ScriptToAsmStr(coin.out.scriptPubKey) + "\nvs:\n"+
ScriptToAsmStr(scriptPubKey);
@ -598,7 +598,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) @@ -598,7 +598,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
CTxIn& txin = mergedTx.vin[i];
const Coin& coin = view.AccessCoin(txin.prevout);
if (coin.IsPruned()) {
if (coin.IsSpent()) {
fComplete = false;
continue;
}

44
src/coins.cpp

@ -10,16 +10,16 @@ @@ -10,16 +10,16 @@
#include <assert.h>
bool CCoinsView::GetCoins(const COutPoint &outpoint, Coin &coin) const { return false; }
bool CCoinsView::HaveCoins(const COutPoint &outpoint) const { return false; }
bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
bool CCoinsView::HaveCoin(const COutPoint &outpoint) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
bool CCoinsViewBacked::GetCoins(const COutPoint &outpoint, Coin &coin) const { return base->GetCoins(outpoint, coin); }
bool CCoinsViewBacked::HaveCoins(const COutPoint &outpoint) const { return base->HaveCoins(outpoint); }
bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); }
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
@ -34,15 +34,15 @@ size_t CCoinsViewCache::DynamicMemoryUsage() const { @@ -34,15 +34,15 @@ size_t CCoinsViewCache::DynamicMemoryUsage() const {
return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
}
CCoinsMap::iterator CCoinsViewCache::FetchCoins(const COutPoint &outpoint) const {
CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
CCoinsMap::iterator it = cacheCoins.find(outpoint);
if (it != cacheCoins.end())
return it;
Coin tmp;
if (!base->GetCoins(outpoint, tmp))
if (!base->GetCoin(outpoint, tmp))
return cacheCoins.end();
CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
if (ret->second.coin.IsPruned()) {
if (ret->second.coin.IsSpent()) {
// The parent only has an empty entry for this outpoint; we can consider our
// version as fresh.
ret->second.flags = CCoinsCacheEntry::FRESH;
@ -51,8 +51,8 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoins(const COutPoint &outpoint) const @@ -51,8 +51,8 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoins(const COutPoint &outpoint) const
return ret;
}
bool CCoinsViewCache::GetCoins(const COutPoint &outpoint, Coin &coin) const {
CCoinsMap::const_iterator it = FetchCoins(outpoint);
bool CCoinsViewCache::GetCoin(const COutPoint &outpoint, Coin &coin) const {
CCoinsMap::const_iterator it = FetchCoin(outpoint);
if (it != cacheCoins.end()) {
coin = it->second.coin;
return true;
@ -61,7 +61,7 @@ bool CCoinsViewCache::GetCoins(const COutPoint &outpoint, Coin &coin) const { @@ -61,7 +61,7 @@ bool CCoinsViewCache::GetCoins(const COutPoint &outpoint, Coin &coin) const {
}
void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) {
assert(!coin.IsPruned());
assert(!coin.IsSpent());
if (coin.out.scriptPubKey.IsUnspendable()) return;
CCoinsMap::iterator it;
bool inserted;
@ -71,7 +71,7 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi @@ -71,7 +71,7 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
}
if (!possible_overwrite) {
if (!it->second.coin.IsPruned()) {
if (!it->second.coin.IsSpent()) {
throw std::logic_error("Adding new coin that replaces non-pruned entry");
}
fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
@ -92,7 +92,7 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) { @@ -92,7 +92,7 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) {
}
void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
CCoinsMap::iterator it = FetchCoins(outpoint);
CCoinsMap::iterator it = FetchCoin(outpoint);
if (it == cacheCoins.end()) return;
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
if (moveout) {
@ -109,7 +109,7 @@ void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) { @@ -109,7 +109,7 @@ void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
static const Coin coinEmpty;
const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = FetchCoins(outpoint);
CCoinsMap::const_iterator it = FetchCoin(outpoint);
if (it == cacheCoins.end()) {
return coinEmpty;
} else {
@ -117,12 +117,12 @@ const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const { @@ -117,12 +117,12 @@ const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
}
}
bool CCoinsViewCache::HaveCoins(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = FetchCoins(outpoint);
return (it != cacheCoins.end() && !it->second.coin.IsPruned());
bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = FetchCoin(outpoint);
return (it != cacheCoins.end() && !it->second.coin.IsSpent());
}
bool CCoinsViewCache::HaveCoinsInCache(const COutPoint &outpoint) const {
bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
return it != cacheCoins.end();
}
@ -144,7 +144,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn @@ -144,7 +144,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
if (itUs == cacheCoins.end()) {
// The parent cache does not have an entry, while the child does
// We can ignore it if it's both FRESH and pruned in the child
if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsPruned())) {
if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
// Otherwise we will need to create it in the parent
// and move the data up and mark it as dirty
CCoinsCacheEntry& entry = cacheCoins[it->first];
@ -162,11 +162,11 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn @@ -162,11 +162,11 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
// parent cache entry has unspent outputs. If this ever happens,
// it means the FRESH flag was misapplied and there is a logic
// error in the calling code.
if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsPruned())
if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent())
throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
// Found the entry in the parent cache
if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsPruned()) {
if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
// The grandparent does not have an entry, and the child is
// modified and being pruned. This means we can just delete
// it from the parent.
@ -229,7 +229,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const @@ -229,7 +229,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsCoinBase()) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
if (!HaveCoins(tx.vin[i].prevout)) {
if (!HaveCoin(tx.vin[i].prevout)) {
return false;
}
}
@ -244,7 +244,7 @@ const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid) @@ -244,7 +244,7 @@ const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
COutPoint iter(txid, 0);
while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
const Coin& alternate = view.AccessCoin(iter);
if (!alternate.IsPruned()) return alternate;
if (!alternate.IsSpent()) return alternate;
++iter.n;
}
return coinEmpty;

24
src/coins.h

@ -58,7 +58,7 @@ public: @@ -58,7 +58,7 @@ public:
template<typename Stream>
void Serialize(Stream &s) const {
assert(!IsPruned());
assert(!IsSpent());
uint32_t code = nHeight * 2 + fCoinBase;
::Serialize(s, VARINT(code));
::Serialize(s, CTxOutCompressor(REF(out)));
@ -73,7 +73,7 @@ public: @@ -73,7 +73,7 @@ public:
::Unserialize(s, REF(CTxOutCompressor(out)));
}
bool IsPruned() const {
bool IsSpent() const {
return out.IsNull();
}
@ -147,11 +147,11 @@ class CCoinsView @@ -147,11 +147,11 @@ class CCoinsView
{
public:
//! Retrieve the Coin (unspent transaction output) for a given outpoint.
virtual bool GetCoins(const COutPoint &outpoint, Coin &coin) const;
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
//! Just check whether we have data for a given outpoint.
//! This may (but cannot always) return true for spent outputs.
virtual bool HaveCoins(const COutPoint &outpoint) const;
virtual bool HaveCoin(const COutPoint &outpoint) const;
//! Retrieve the block hash whose state this CCoinsView currently represents
virtual uint256 GetBestBlock() const;
@ -179,8 +179,8 @@ protected: @@ -179,8 +179,8 @@ protected:
public:
CCoinsViewBacked(CCoinsView *viewIn);
bool GetCoins(const COutPoint &outpoint, Coin &coin) const override;
bool HaveCoins(const COutPoint &outpoint) const override;
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
bool HaveCoin(const COutPoint &outpoint) const override;
uint256 GetBestBlock() const override;
void SetBackend(CCoinsView &viewIn);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;
@ -207,22 +207,22 @@ public: @@ -207,22 +207,22 @@ public:
CCoinsViewCache(CCoinsView *baseIn);
// Standard CCoinsView methods
bool GetCoins(const COutPoint &outpoint, Coin &coin) const;
bool HaveCoins(const COutPoint &outpoint) const;
bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
bool HaveCoin(const COutPoint &outpoint) const;
uint256 GetBestBlock() const;
void SetBestBlock(const uint256 &hashBlock);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
/**
* Check if we have the given utxo already loaded in this cache.
* The semantics are the same as HaveCoins(), but no calls to
* The semantics are the same as HaveCoin(), but no calls to
* the backing CCoinsView are made.
*/
bool HaveCoinsInCache(const COutPoint &outpoint) const;
bool HaveCoinInCache(const COutPoint &outpoint) const;
/**
* Return a reference to Coin in the cache, or a pruned one if not found. This is
* more efficient than GetCoins. Modifications to other cache entries are
* more efficient than GetCoin. Modifications to other cache entries are
* allowed while accessing the returned pointer.
*/
const Coin& AccessCoin(const COutPoint &output) const;
@ -273,7 +273,7 @@ public: @@ -273,7 +273,7 @@ public:
bool HaveInputs(const CTransaction& tx) const;
private:
CCoinsMap::iterator FetchCoins(const COutPoint &outpoint) const;
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;
/**
* By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.

2
src/consensus/tx_verify.cpp

@ -214,7 +214,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c @@ -214,7 +214,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c
{
const COutPoint &prevout = tx.vin[i].prevout;
const Coin& coin = inputs.AccessCoin(prevout);
assert(!coin.IsPruned());
assert(!coin.IsSpent());
// If prev is coinbase, check that it's matured
if (coin.IsCoinBase()) {

4
src/init.cpp

@ -146,9 +146,9 @@ class CCoinsViewErrorCatcher : public CCoinsViewBacked @@ -146,9 +146,9 @@ class CCoinsViewErrorCatcher : public CCoinsViewBacked
{
public:
CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
bool GetCoins(const COutPoint &outpoint, Coin &coin) const override {
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override {
try {
return CCoinsViewBacked::GetCoins(outpoint, coin);
return CCoinsViewBacked::GetCoin(outpoint, coin);
} catch(const std::runtime_error& e) {
uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
LogPrintf("Error reading from database: %s\n", e.what());

4
src/net_processing.cpp

@ -914,8 +914,8 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) @@ -914,8 +914,8 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
return recentRejects->contains(inv.hash) ||
mempool.exists(inv.hash) ||
mapOrphanTransactions.count(inv.hash) ||
pcoinsTip->HaveCoinsInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
pcoinsTip->HaveCoinsInCache(COutPoint(inv.hash, 1));
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 1));
}
case MSG_BLOCK:
case MSG_WITNESS_BLOCK:

2
src/qt/transactiondesc.cpp

@ -294,7 +294,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco @@ -294,7 +294,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
COutPoint prevout = txin.prevout;
Coin prev;
if(pcoinsTip->GetCoins(prevout, prev))
if(pcoinsTip->GetCoin(prevout, prev))
{
{
strHTML += "<li>";

2
src/rest.cpp

@ -514,7 +514,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) @@ -514,7 +514,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
for (size_t i = 0; i < vOutPoints.size(); i++) {
bool hit = false;
Coin coin;
if (view.GetCoins(vOutPoints[i], coin) && !mempool.isSpent(vOutPoints[i])) {
if (view.GetCoin(vOutPoints[i], coin) && !mempool.isSpent(vOutPoints[i])) {
hit = true;
outs.emplace_back(std::move(coin));
}

4
src/rpc/blockchain.cpp

@ -985,11 +985,11 @@ UniValue gettxout(const JSONRPCRequest& request) @@ -985,11 +985,11 @@ UniValue gettxout(const JSONRPCRequest& request)
if (fMempool) {
LOCK(mempool.cs);
CCoinsViewMemPool view(pcoinsTip, mempool);
if (!view.GetCoins(out, coin) || mempool.isSpent(out)) { // TODO: filtering spent coins should be done by the CCoinsViewMemPool
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) { // TODO: filtering spent coins should be done by the CCoinsViewMemPool
return NullUniValue;
}
} else {
if (!pcoinsTip->GetCoins(out, coin)) {
if (!pcoinsTip->GetCoin(out, coin)) {
return NullUniValue;
}
}

8
src/rpc/rawtransaction.cpp

@ -220,7 +220,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request) @@ -220,7 +220,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
pblockindex = mapBlockIndex[hashBlock];
} else {
const Coin& coin = AccessByTxid(*pcoinsTip, oneTxid);
if (!coin.IsPruned() && coin.nHeight > 0 && coin.nHeight <= chainActive.Height()) {
if (!coin.IsSpent() && coin.nHeight > 0 && coin.nHeight <= chainActive.Height()) {
pblockindex = chainActive[coin.nHeight];
}
}
@ -696,7 +696,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) @@ -696,7 +696,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
{
const Coin& coin = view.AccessCoin(out);
if (!coin.IsPruned() && coin.out.scriptPubKey != scriptPubKey) {
if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
std::string err("Previous output scriptPubKey mismatch:\n");
err = err + ScriptToAsmStr(coin.out.scriptPubKey) + "\nvs:\n"+
ScriptToAsmStr(scriptPubKey);
@ -768,7 +768,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) @@ -768,7 +768,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
CTxIn& txin = mergedTx.vin[i];
const Coin& coin = view.AccessCoin(txin.prevout);
if (coin.IsPruned()) {
if (coin.IsSpent()) {
TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
continue;
}
@ -848,7 +848,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) @@ -848,7 +848,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
bool fHaveChain = false;
for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) {
const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
fHaveChain = !existingCoin.IsPruned();
fHaveChain = !existingCoin.IsSpent();
}
bool fHaveMempool = mempool.exists(hashTx);
if (!fHaveMempool && !fHaveChain) {

90
src/test/coins_tests.cpp

@ -25,7 +25,7 @@ namespace @@ -25,7 +25,7 @@ namespace
//! equality test
bool operator==(const Coin &a, const Coin &b) {
// Empty Coin objects are always equal.
if (a.IsPruned() && b.IsPruned()) return true;
if (a.IsSpent() && b.IsSpent()) return true;
return a.fCoinBase == b.fCoinBase &&
a.nHeight == b.nHeight &&
a.out == b.out;
@ -37,24 +37,24 @@ class CCoinsViewTest : public CCoinsView @@ -37,24 +37,24 @@ class CCoinsViewTest : public CCoinsView
std::map<COutPoint, Coin> map_;
public:
bool GetCoins(const COutPoint& outpoint, Coin& coin) const
bool GetCoin(const COutPoint& outpoint, Coin& coin) const
{
std::map<COutPoint, Coin>::const_iterator it = map_.find(outpoint);
if (it == map_.end()) {
return false;
}
coin = it->second;
if (coin.IsPruned() && insecure_rand() % 2 == 0) {
if (coin.IsSpent() && insecure_rand() % 2 == 0) {
// Randomly return false in case of an empty entry.
return false;
}
return true;
}
bool HaveCoins(const COutPoint& outpoint) const
bool HaveCoin(const COutPoint& outpoint) const
{
Coin coin;
return GetCoins(outpoint, coin);
return GetCoin(outpoint, coin);
}
uint256 GetBestBlock() const { return hashBestBlock_; }
@ -65,7 +65,7 @@ public: @@ -65,7 +65,7 @@ public:
if (it->second.flags & CCoinsCacheEntry::DIRTY) {
// Same optimization used in CCoinsViewDB is to only write dirty entries.
map_[it->first] = it->second.coin;
if (it->second.coin.IsPruned() && insecure_rand() % 3 == 0) {
if (it->second.coin.IsSpent() && insecure_rand() % 3 == 0) {
// Randomly delete empty entries on write.
map_.erase(it->first);
}
@ -151,20 +151,20 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) @@ -151,20 +151,20 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
const Coin& entry = (insecure_rand() % 500 == 0) ? AccessByTxid(*stack.back(), txid) : stack.back()->AccessCoin(COutPoint(txid, 0));
BOOST_CHECK(coin == entry);
if (insecure_rand() % 5 == 0 || coin.IsPruned()) {
if (insecure_rand() % 5 == 0 || coin.IsSpent()) {
Coin newcoin;
newcoin.out.nValue = insecure_rand();
newcoin.nHeight = 1;
if (insecure_rand() % 16 == 0 && coin.IsPruned()) {
if (insecure_rand() % 16 == 0 && coin.IsSpent()) {
newcoin.out.scriptPubKey.assign(1 + (insecure_rand() & 0x3F), OP_RETURN);
BOOST_CHECK(newcoin.out.scriptPubKey.IsUnspendable());
added_an_unspendable_entry = true;
} else {
newcoin.out.scriptPubKey.assign(insecure_rand() & 0x3F, 0); // Random sizes so we can test memory usage accounting
(coin.IsPruned() ? added_an_entry : updated_an_entry) = true;
(coin.IsSpent() ? added_an_entry : updated_an_entry) = true;
coin = newcoin;
}
stack.back()->AddCoin(COutPoint(txid, 0), std::move(newcoin), !coin.IsPruned() || insecure_rand() & 1);
stack.back()->AddCoin(COutPoint(txid, 0), std::move(newcoin), !coin.IsSpent() || insecure_rand() & 1);
} else {
removed_an_entry = true;
coin.Clear();
@ -177,20 +177,20 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) @@ -177,20 +177,20 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
COutPoint out(txids[insecure_rand() % txids.size()], 0);
int cacheid = insecure_rand() % stack.size();
stack[cacheid]->Uncache(out);
uncached_an_entry |= !stack[cacheid]->HaveCoinsInCache(out);
uncached_an_entry |= !stack[cacheid]->HaveCoinInCache(out);
}
// Once every 1000 iterations and at the end, verify the full cache.
if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) {
for (auto it = result.begin(); it != result.end(); it++) {
bool have = stack.back()->HaveCoins(it->first);
bool have = stack.back()->HaveCoin(it->first);
const Coin& coin = stack.back()->AccessCoin(it->first);
BOOST_CHECK(have == !coin.IsPruned());
BOOST_CHECK(have == !coin.IsSpent());
BOOST_CHECK(coin == it->second);
if (coin.IsPruned()) {
if (coin.IsSpent()) {
missed_an_entry = true;
} else {
BOOST_CHECK(stack.back()->HaveCoinsInCache(it->first));
BOOST_CHECK(stack.back()->HaveCoinInCache(it->first));
found_an_entry = true;
}
}
@ -281,9 +281,9 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -281,9 +281,9 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
stack.push_back(new CCoinsViewCacheTest(&base)); // Start with one cache.
// Track the txids we've used in various sets
std::set<COutPoint> coinbaseids;
std::set<COutPoint> disconnectedids;
std::set<COutPoint> duplicateids;
std::set<COutPoint> coinbase_coins;
std::set<COutPoint> disconnected_coins;
std::set<COutPoint> duplicate_coins;
std::set<COutPoint> utxoset;
for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) {
@ -297,22 +297,22 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -297,22 +297,22 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
tx.vout[0].nValue = i; //Keep txs unique unless intended to duplicate
tx.vout[0].scriptPubKey.assign(insecure_rand() & 0x3F, 0); // Random sizes so we can test memory usage accounting
unsigned int height = insecure_rand();
Coin oldcoins;
Coin old_coin;
// 2/20 times create a new coinbase
if (randiter % 20 < 2 || coinbaseids.size() < 10) {
if (randiter % 20 < 2 || coinbase_coins.size() < 10) {
// 1/10 of those times create a duplicate coinbase
if (insecure_rand() % 10 == 0 && coinbaseids.size()) {
auto utxod = FindRandomFrom(coinbaseids);
if (insecure_rand() % 10 == 0 && coinbase_coins.size()) {
auto utxod = FindRandomFrom(coinbase_coins);
// Reuse the exact same coinbase
tx = std::get<0>(utxod->second);
// shouldn't be available for reconnection if its been duplicated
disconnectedids.erase(utxod->first);
disconnected_coins.erase(utxod->first);
duplicateids.insert(utxod->first);
duplicate_coins.insert(utxod->first);
}
else {
coinbaseids.insert(COutPoint(tx.GetHash(), 0));
coinbase_coins.insert(COutPoint(tx.GetHash(), 0));
}
assert(CTransaction(tx).IsCoinBase());
}
@ -322,21 +322,21 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -322,21 +322,21 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
COutPoint prevout;
// 1/20 times reconnect a previously disconnected tx
if (randiter % 20 == 2 && disconnectedids.size()) {
auto utxod = FindRandomFrom(disconnectedids);
if (randiter % 20 == 2 && disconnected_coins.size()) {
auto utxod = FindRandomFrom(disconnected_coins);
tx = std::get<0>(utxod->second);
prevout = tx.vin[0].prevout;
if (!CTransaction(tx).IsCoinBase() && !utxoset.count(prevout)) {
disconnectedids.erase(utxod->first);
disconnected_coins.erase(utxod->first);
continue;
}
// If this tx is already IN the UTXO, then it must be a coinbase, and it must be a duplicate
if (utxoset.count(utxod->first)) {
assert(CTransaction(tx).IsCoinBase());
assert(duplicateids.count(utxod->first));
assert(duplicate_coins.count(utxod->first));
}
disconnectedids.erase(utxod->first);
disconnected_coins.erase(utxod->first);
}
// 16/20 times create a regular tx
@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
assert(!CTransaction(tx).IsCoinBase());
}
// In this simple test coins only have two states, spent or unspent, save the unspent state to restore
oldcoins = result[prevout];
old_coin = result[prevout];
// Update the expected result of prevouthash to know these coins are spent
result[prevout].Clear();
@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
// The test is designed to ensure spending a duplicate coinbase will work properly
// if that ever happens and not resurrect the previously overwritten coinbase
if (duplicateids.count(prevout)) {
if (duplicate_coins.count(prevout)) {
spent_a_duplicate_coinbase = true;
}
@ -375,21 +375,21 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -375,21 +375,21 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
utxoset.insert(outpoint);
// Track this tx and undo info to use later
utxoData.emplace(outpoint, std::make_tuple(tx,undo,oldcoins));
utxoData.emplace(outpoint, std::make_tuple(tx,undo,old_coin));
} else if (utxoset.size()) {
//1/20 times undo a previous transaction
auto utxod = FindRandomFrom(utxoset);
CTransaction &tx = std::get<0>(utxod->second);
CTxUndo &undo = std::get<1>(utxod->second);
Coin &origcoins = std::get<2>(utxod->second);
Coin &orig_coin = std::get<2>(utxod->second);
// Update the expected result
// Remove new outputs
result[utxod->first].Clear();
// If not coinbase restore prevout
if (!tx.IsCoinBase()) {
result[tx.vin[0].prevout] = origcoins;
result[tx.vin[0].prevout] = orig_coin;
}
// Disconnect the tx from the current UTXO
@ -403,7 +403,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -403,7 +403,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
ApplyTxInUndo(std::move(coin), *(stack.back()), out);
}
// Store as a candidate for reconnection
disconnectedids.insert(utxod->first);
disconnected_coins.insert(utxod->first);
// Update the utxoset
utxoset.erase(utxod->first);
@ -414,9 +414,9 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -414,9 +414,9 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
// Once every 1000 iterations and at the end, verify the full cache.
if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) {
for (auto it = result.begin(); it != result.end(); it++) {
bool have = stack.back()->HaveCoins(it->first);
bool have = stack.back()->HaveCoin(it->first);
const Coin& coin = stack.back()->AccessCoin(it->first);
BOOST_CHECK(have == !coin.IsPruned());
BOOST_CHECK(have == !coin.IsSpent());
BOOST_CHECK(coin == it->second);
}
}
@ -425,11 +425,11 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) @@ -425,11 +425,11 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
if (utxoset.size() > 1 && insecure_rand() % 30) {
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(utxoset)->first);
}
if (disconnectedids.size() > 1 && insecure_rand() % 30) {
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(disconnectedids)->first);
if (disconnected_coins.size() > 1 && insecure_rand() % 30) {
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(disconnected_coins)->first);
}
if (duplicateids.size() > 1 && insecure_rand() % 30) {
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(duplicateids)->first);
if (duplicate_coins.size() > 1 && insecure_rand() % 30) {
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(duplicate_coins)->first);
}
if (insecure_rand() % 100 == 0) {
@ -537,11 +537,11 @@ void SetCoinsValue(CAmount value, Coin& coin) @@ -537,11 +537,11 @@ void SetCoinsValue(CAmount value, Coin& coin)
{
assert(value != ABSENT);
coin.Clear();
assert(coin.IsPruned());
assert(coin.IsSpent());
if (value != PRUNED) {
coin.out.nValue = value;
coin.nHeight = 1;
assert(!coin.IsPruned());
assert(!coin.IsSpent());
}
}
@ -567,7 +567,7 @@ void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags) @@ -567,7 +567,7 @@ void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags)
value = ABSENT;
flags = NO_ENTRY;
} else {
if (it->second.coin.IsPruned()) {
if (it->second.coin.IsSpent()) {
value = PRUNED;
} else {
value = it->second.coin.out.nValue;

20
src/txdb.cpp

@ -27,10 +27,10 @@ static const char DB_LAST_BLOCK = 'l'; @@ -27,10 +27,10 @@ static const char DB_LAST_BLOCK = 'l';
namespace {
struct CoinsEntry {
struct CoinEntry {
COutPoint* outpoint;
char key;
CoinsEntry(const COutPoint* ptr) : outpoint(const_cast<COutPoint*>(ptr)), key(DB_COIN) {}
CoinEntry(const COutPoint* ptr) : outpoint(const_cast<COutPoint*>(ptr)), key(DB_COIN) {}
template<typename Stream>
void Serialize(Stream &s) const {
@ -53,12 +53,12 @@ CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(Get @@ -53,12 +53,12 @@ CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(Get
{
}
bool CCoinsViewDB::GetCoins(const COutPoint &outpoint, Coin &coin) const {
return db.Read(CoinsEntry(&outpoint), coin);
bool CCoinsViewDB::GetCoin(const COutPoint &outpoint, Coin &coin) const {
return db.Read(CoinEntry(&outpoint), coin);
}
bool CCoinsViewDB::HaveCoins(const COutPoint &outpoint) const {
return db.Exists(CoinsEntry(&outpoint));
bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
return db.Exists(CoinEntry(&outpoint));
}
uint256 CCoinsViewDB::GetBestBlock() const {
@ -74,8 +74,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { @@ -74,8 +74,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
size_t changed = 0;
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) {
CoinsEntry entry(&it->first);
if (it->second.coin.IsPruned())
CoinEntry entry(&it->first);
if (it->second.coin.IsSpent())
batch.Erase(entry);
else
batch.Write(entry, it->second.coin);
@ -130,7 +130,7 @@ CCoinsViewCursor *CCoinsViewDB::Cursor() const @@ -130,7 +130,7 @@ CCoinsViewCursor *CCoinsViewDB::Cursor() const
i->pcursor->Seek(DB_COIN);
// Cache key of first record
if (i->pcursor->Valid()) {
CoinsEntry entry(&i->keyTmp.second);
CoinEntry entry(&i->keyTmp.second);
i->pcursor->GetKey(entry);
i->keyTmp.first = entry.key;
} else {
@ -167,7 +167,7 @@ bool CCoinsViewDBCursor::Valid() const @@ -167,7 +167,7 @@ bool CCoinsViewDBCursor::Valid() const
void CCoinsViewDBCursor::Next()
{
pcursor->Next();
CoinsEntry entry(&keyTmp.second);
CoinEntry entry(&keyTmp.second);
if (!pcursor->Valid() || !pcursor->GetKey(entry)) {
keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false
} else {

4
src/txdb.h

@ -71,8 +71,8 @@ protected: @@ -71,8 +71,8 @@ protected:
public:
CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
bool GetCoins(const COutPoint &outpoint, Coin &coin) const override;
bool HaveCoins(const COutPoint &outpoint) const override;
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
bool HaveCoin(const COutPoint &outpoint) const override;
uint256 GetBestBlock() const override;
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;
CCoinsViewCursor *Cursor() const override;

14
src/txmempool.cpp

@ -525,8 +525,8 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem @@ -525,8 +525,8 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
if (it2 != mapTx.end())
continue;
const Coin &coin = pcoins->AccessCoin(txin.prevout);
if (nCheckFrequency != 0) assert(!coin.IsPruned());
if (coin.IsPruned() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) {
if (nCheckFrequency != 0) assert(!coin.IsSpent());
if (coin.IsSpent() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) {
txToRemove.insert(it);
break;
}
@ -654,7 +654,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const @@ -654,7 +654,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
parentSigOpCost += it2->GetSigOpCost();
}
} else {
assert(pcoins->HaveCoins(txin.prevout));
assert(pcoins->HaveCoin(txin.prevout));
}
// Check whether its inputs are marked in mapNextTx.
auto it3 = mapNextTx.find(txin.prevout);
@ -890,7 +890,7 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const @@ -890,7 +890,7 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
bool CCoinsViewMemPool::GetCoins(const COutPoint &outpoint, Coin &coin) const {
bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
// If an entry in the mempool exists, always return that one, as it's guaranteed to never
// conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
// transactions. First checking the underlying cache risks returning a pruned entry instead.
@ -903,11 +903,11 @@ bool CCoinsViewMemPool::GetCoins(const COutPoint &outpoint, Coin &coin) const { @@ -903,11 +903,11 @@ bool CCoinsViewMemPool::GetCoins(const COutPoint &outpoint, Coin &coin) const {
return false;
}
}
return (base->GetCoins(outpoint, coin) && !coin.IsPruned());
return (base->GetCoin(outpoint, coin) && !coin.IsSpent());
}
bool CCoinsViewMemPool::HaveCoins(const COutPoint &outpoint) const {
return mempool.exists(outpoint) || base->HaveCoins(outpoint);
bool CCoinsViewMemPool::HaveCoin(const COutPoint &outpoint) const {
return mempool.exists(outpoint) || base->HaveCoin(outpoint);
}
size_t CTxMemPool::DynamicMemoryUsage() const {

4
src/txmempool.h

@ -679,8 +679,8 @@ protected: @@ -679,8 +679,8 @@ protected:
public:
CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn);
bool GetCoins(const COutPoint &outpoint, Coin &coin) const;
bool HaveCoins(const COutPoint &outpoint) const;
bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
bool HaveCoin(const COutPoint &outpoint) const;
};
#endif // BITCOIN_TXMEMPOOL_H

34
src/validation.cpp

@ -269,7 +269,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool @@ -269,7 +269,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
const CTxIn& txin = tx.vin[txinIndex];
Coin coin;
if (!viewMemPool.GetCoins(txin.prevout, coin)) {
if (!viewMemPool.GetCoin(txin.prevout, coin)) {
return error("%s: Missing input", __func__);
}
if (coin.nHeight == MEMPOOL_HEIGHT) {
@ -344,7 +344,7 @@ static bool IsCurrentForFeeEstimation() @@ -344,7 +344,7 @@ static bool IsCurrentForFeeEstimation()
bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx, bool fLimitFree,
bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector<COutPoint>& vHashTxnToUncache)
bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector<COutPoint>& coins_to_uncache)
{
const CTransaction& tx = *ptx;
const uint256 hash = tx.GetHash();
@ -439,10 +439,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C @@ -439,10 +439,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// do we already have it?
for (size_t out = 0; out < tx.vout.size(); out++) {
COutPoint outpoint(hash, out);
bool fHadTxInCache = pcoinsTip->HaveCoinsInCache(outpoint);
if (view.HaveCoins(outpoint)) {
if (!fHadTxInCache) {
vHashTxnToUncache.push_back(outpoint);
bool had_coin_in_cache = pcoinsTip->HaveCoinInCache(outpoint);
if (view.HaveCoin(outpoint)) {
if (!had_coin_in_cache) {
coins_to_uncache.push_back(outpoint);
}
return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known");
}
@ -450,10 +450,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C @@ -450,10 +450,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// do all inputs exist?
BOOST_FOREACH(const CTxIn txin, tx.vin) {
if (!pcoinsTip->HaveCoinsInCache(txin.prevout)) {
vHashTxnToUncache.push_back(txin.prevout);
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
coins_to_uncache.push_back(txin.prevout);
}
if (!view.HaveCoins(txin.prevout)) {
if (!view.HaveCoin(txin.prevout)) {
if (pfMissingInputs) {
*pfMissingInputs = true;
}
@ -763,10 +763,10 @@ bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const @@ -763,10 +763,10 @@ bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const
bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
bool fOverrideMempoolLimit, const CAmount nAbsurdFee)
{
std::vector<COutPoint> vHashTxToUncache;
bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, vHashTxToUncache);
std::vector<COutPoint> coins_to_uncache;
bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache);
if (!res) {
BOOST_FOREACH(const COutPoint& hashTx, vHashTxToUncache)
BOOST_FOREACH(const COutPoint& hashTx, coins_to_uncache)
pcoinsTip->Uncache(hashTx);
}
// After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
@ -819,7 +819,7 @@ bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus @@ -819,7 +819,7 @@ bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus
if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
const Coin& coin = AccessByTxid(*pcoinsTip, hash);
if (!coin.IsPruned()) pindexSlow = chainActive[coin.nHeight];
if (!coin.IsSpent()) pindexSlow = chainActive[coin.nHeight];
}
if (pindexSlow) {
@ -1117,7 +1117,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi @@ -1117,7 +1117,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
for (unsigned int i = 0; i < tx.vin.size(); i++) {
const COutPoint &prevout = tx.vin[i].prevout;
const Coin& coin = inputs.AccessCoin(prevout);
assert(!coin.IsPruned());
assert(!coin.IsSpent());
// We very carefully only pass in things to CScriptCheck which
// are clearly committed to by tx' witness hash. This provides
@ -1254,14 +1254,14 @@ int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out) @@ -1254,14 +1254,14 @@ int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out)
{
bool fClean = true;
if (view.HaveCoins(out)) fClean = false; // overwriting transaction output
if (view.HaveCoin(out)) fClean = false; // overwriting transaction output
if (undo.nHeight == 0) {
// Missing undo metadata (height and coinbase). Older versions included this
// information only in undo records for the last spend of a transactions'
// outputs. This implies that it must be present for some other output of the same tx.
const Coin& alternate = AccessByTxid(view, out.hash);
if (!alternate.IsPruned()) {
if (!alternate.IsSpent()) {
undo.nHeight = alternate.nHeight;
undo.fCoinBase = alternate.fCoinBase;
} else {
@ -1510,7 +1510,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd @@ -1510,7 +1510,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
if (fEnforceBIP30) {
for (const auto& tx : block.vtx) {
for (size_t o = 0; o < tx->vout.size(); o++) {
if (view.HaveCoins(COutPoint(tx->GetHash(), o))) {
if (view.HaveCoin(COutPoint(tx->GetHash(), o))) {
return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
REJECT_INVALID, "bad-txns-BIP30");
}

Loading…
Cancel
Save