aboutsummaryrefslogtreecommitdiff
path: root/src/coins.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/coins.cpp')
-rw-r--r--src/coins.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index b45fc76338..b5dc6197bd 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -11,16 +11,22 @@
#include <assert.h>
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(); }
+std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
+bool CCoinsView::HaveCoin(const COutPoint &outpoint) const
+{
+ Coin coin;
+ return GetCoin(outpoint, coin);
+}
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
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(); }
+std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
@@ -55,7 +61,7 @@ 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;
+ return !coin.IsSpent();
}
return false;
}
@@ -81,19 +87,20 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
}
-void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) {
+void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, bool check) {
bool fCoinbase = tx.IsCoinBase();
const uint256& txid = tx.GetHash();
for (size_t i = 0; i < tx.vout.size(); ++i) {
- // Pass fCoinbase as the possible_overwrite flag to AddCoin, in order to correctly
+ bool overwrite = check ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
+ // Always set the possible_overwrite flag to AddCoin for coinbase txn, in order to correctly
// deal with the pre-BIP30 occurrences of duplicate coinbase transactions.
- cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), fCoinbase);
+ cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), overwrite);
}
}
-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);
@@ -104,6 +111,7 @@ void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
it->second.flags |= CCoinsCacheEntry::DIRTY;
it->second.coin.Clear();
}
+ return true;
}
static const Coin coinEmpty;
@@ -124,7 +132,7 @@ bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
- return it != cacheCoins.end();
+ return (it != cacheCoins.end() && !it->second.coin.IsSpent());
}
uint256 CCoinsViewCache::GetBestBlock() const {