Change CCoinsMapKey to use chain-aware outpoints

This commit is contained in:
Steven Roose 2018-12-11 17:39:20 +01:00
parent 22ec499327
commit 0d07d21a2e
2 changed files with 40 additions and 26 deletions

View file

@ -37,14 +37,22 @@ size_t CCoinsViewCache::DynamicMemoryUsage() const {
return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
}
// ELEMENTS:
// Create a CCoinsMapKey for non-PEGIN utxo.
static inline CCoinsMapKey native_key(const COutPoint& outpoint) {
return std::make_pair(uint256(), outpoint);
}
CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
CCoinsMap::iterator it = cacheCoins.find(outpoint);
CCoinsMap::iterator it = cacheCoins.find(native_key(outpoint));
if (it != cacheCoins.end())
return it;
Coin 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;
CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct,
std::forward_as_tuple(native_key(outpoint)),
std::forward_as_tuple(std::move(tmp))).first;
if (ret->second.coin.IsSpent()) {
// The parent only has an empty entry for this outpoint; we can consider our
// version as fresh.
@ -68,7 +76,8 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
if (coin.out.scriptPubKey.IsUnspendable()) return;
CCoinsMap::iterator it;
bool inserted;
std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct,
std::forward_as_tuple(native_key(outpoint)), std::tuple<>());
bool fresh = false;
if (!inserted) {
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
@ -128,7 +137,7 @@ bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
}
bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
CCoinsMap::const_iterator it = cacheCoins.find(native_key(outpoint));
return (it != cacheCoins.end() && !it->second.coin.IsSpent());
}
@ -207,9 +216,9 @@ bool CCoinsViewCache::Flush() {
return fOk;
}
void CCoinsViewCache::Uncache(const COutPoint& hash)
void CCoinsViewCache::Uncache(const COutPoint& point)
{
CCoinsMap::iterator it = cacheCoins.find(hash);
CCoinsMap::iterator it = cacheCoins.find(native_key(point));
if (it != cacheCoins.end() && it->second.flags == 0) {
cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
cacheCoins.erase(it);

View file

@ -81,25 +81,6 @@ public:
}
};
class SaltedOutpointHasher
{
private:
/** Salt */
const uint64_t k0, k1;
public:
SaltedOutpointHasher();
/**
* This *must* return size_t. With Boost 1.46 on 32-bit systems the
* unordered_map will behave unpredictably if the custom hasher returns a
* uint64_t, resulting in failures when syncing the chain (#4634).
*/
size_t operator()(const COutPoint& id) const {
return SipHashUint256Extra(k0, k1, id.hash, id.n);
}
};
struct CCoinsCacheEntry
{
Coin coin; // The actual cached data.
@ -119,7 +100,31 @@ struct CCoinsCacheEntry
explicit CCoinsCacheEntry(Coin&& coin_) : coin(std::move(coin_)), flags(0) {}
};
typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;
// For PEGIN entries, the first is the genesis hash, the second is the outpoint.
// For ~PEGIN entries, the first is zero, the second is the outpoint.
typedef std::pair<uint256, COutPoint> CCoinsMapKey;
class SaltedOutpointHasher
{
private:
/** Salt */
const uint64_t k0, k1;
public:
SaltedOutpointHasher();
/**
* This *must* return size_t. With Boost 1.46 on 32-bit systems the
* unordered_map will behave unpredictably if the custom hasher returns a
* uint64_t, resulting in failures when syncing the chain (#4634).
*/
size_t operator()(const CCoinsMapKey& key) const {
return SipHashUint256(k0, k1, key.first) ^ SipHashUint256Extra(k0, k1, key.second.hash, key.second.n);
}
size_t operator()(const COutPoint& id) const {
return SipHashUint256Extra(k0, k1, id.hash, id.n);
}
};
typedef std::unordered_map<CCoinsMapKey, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;
/** Cursor for iterating over CoinsView state */
class CCoinsViewCursor