mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-13 12:33:42 +02:00
Change CCoinsMapKey to use chain-aware outpoints
This commit is contained in:
parent
22ec499327
commit
0d07d21a2e
2 changed files with 40 additions and 26 deletions
|
|
@ -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);
|
||||
|
|
|
|||
45
src/coins.h
45
src/coins.h
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue