aboutsummaryrefslogtreecommitdiff
path: root/src/coins.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/coins.cpp')
-rw-r--r--src/coins.cpp29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index 86b2a6ef1..fe40911db 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -4,6 +4,8 @@
#include "coins.h"
+#include "random.h"
+
#include <assert.h>
// calculate number of bytes for the bitmask, and its number of non-zero bytes
@@ -55,7 +57,7 @@ bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return fal
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
uint256 CCoinsView::GetBestBlock() { return uint256(0); }
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
-bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return false; }
+bool CCoinsView::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
@@ -66,9 +68,11 @@ bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(t
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
-bool CCoinsViewBacked::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
+bool CCoinsViewBacked::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
+CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
+
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
@@ -83,20 +87,20 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
return false;
}
-std::map<uint256,CCoins>::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
- std::map<uint256,CCoins>::iterator it = cacheCoins.lower_bound(txid);
- if (it != cacheCoins.end() && it->first == txid)
+CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
+ CCoinsMap::iterator it = cacheCoins.find(txid);
+ if (it != cacheCoins.end())
return it;
CCoins tmp;
if (!base->GetCoins(txid,tmp))
return cacheCoins.end();
- std::map<uint256,CCoins>::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins()));
+ CCoinsMap::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins()));
tmp.swap(ret->second);
return ret;
}
CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) {
- std::map<uint256,CCoins>::iterator it = FetchCoins(txid);
+ CCoinsMap::iterator it = FetchCoins(txid);
assert(it != cacheCoins.end());
return it->second;
}
@@ -107,7 +111,12 @@ bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) {
}
bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
- return FetchCoins(txid) != cacheCoins.end();
+ CCoinsMap::iterator it = FetchCoins(txid);
+ // We're using vtx.empty() instead of IsPruned here for performance reasons,
+ // as we only care about the case where an transaction was replaced entirely
+ // in a reorganization (which wipes vout entirely, as opposed to spending
+ // which just cleans individual outputs).
+ return (it != cacheCoins.end() && !it->second.vout.empty());
}
uint256 CCoinsViewCache::GetBestBlock() {
@@ -121,8 +130,8 @@ bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
return true;
}
-bool CCoinsViewCache::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlockIn) {
- for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
+bool CCoinsViewCache::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
+ for (CCoinsMap::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
cacheCoins[it->first] = it->second;
hashBlock = hashBlockIn;
return true;