Skip to content

Commit 382c871

Browse files
committed
Use SipHash-2-4 for CCoinsCache index
This is ~1.7x slower than the Lookup3-of-Xor-with-salt construct we were using before, but it is a primitive designed for exactly this.
1 parent 0b1295b commit 382c871

File tree

4 files changed

+13
-76
lines changed

4 files changed

+13
-76
lines changed

src/coins.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
5656
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
5757
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
5858

59-
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
59+
SaltedTxidHasher::SaltedTxidHasher()
60+
{
61+
GetRandBytes((unsigned char*)&k0, sizeof(k0));
62+
GetRandBytes((unsigned char*)&k1, sizeof(k1));
63+
}
6064

6165
CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { }
6266

src/coins.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "compressor.h"
1010
#include "core_memusage.h"
11+
#include "hash.h"
1112
#include "memusage.h"
1213
#include "serialize.h"
1314
#include "uint256.h"
@@ -264,21 +265,22 @@ class CCoins
264265
}
265266
};
266267

267-
class CCoinsKeyHasher
268+
class SaltedTxidHasher
268269
{
269270
private:
270-
uint256 salt;
271+
/** Salt */
272+
uint64_t k0, k1;
271273

272274
public:
273-
CCoinsKeyHasher();
275+
SaltedTxidHasher();
274276

275277
/**
276278
* This *must* return size_t. With Boost 1.46 on 32-bit systems the
277279
* unordered_map will behave unpredictably if the custom hasher returns a
278280
* uint64_t, resulting in failures when syncing the chain (#4634).
279281
*/
280-
size_t operator()(const uint256& key) const {
281-
return key.GetHash(salt);
282+
size_t operator()(const uint256& txid) const {
283+
return SipHashUint256(k0, k1, txid);
282284
}
283285
};
284286

@@ -295,7 +297,7 @@ struct CCoinsCacheEntry
295297
CCoinsCacheEntry() : coins(), flags(0) {}
296298
};
297299

298-
typedef boost::unordered_map<uint256, CCoinsCacheEntry, CCoinsKeyHasher> CCoinsMap;
300+
typedef boost::unordered_map<uint256, CCoinsCacheEntry, SaltedTxidHasher> CCoinsMap;
299301

300302
/** Cursor for iterating over CoinsView state */
301303
class CCoinsViewCursor

src/uint256.cpp

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -80,67 +80,3 @@ template std::string base_blob<256>::GetHex() const;
8080
template std::string base_blob<256>::ToString() const;
8181
template void base_blob<256>::SetHex(const char*);
8282
template void base_blob<256>::SetHex(const std::string&);
83-
84-
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
85-
{
86-
// Taken from lookup3, by Bob Jenkins.
87-
a -= c;
88-
a ^= ((c << 4) | (c >> 28));
89-
c += b;
90-
b -= a;
91-
b ^= ((a << 6) | (a >> 26));
92-
a += c;
93-
c -= b;
94-
c ^= ((b << 8) | (b >> 24));
95-
b += a;
96-
a -= c;
97-
a ^= ((c << 16) | (c >> 16));
98-
c += b;
99-
b -= a;
100-
b ^= ((a << 19) | (a >> 13));
101-
a += c;
102-
c -= b;
103-
c ^= ((b << 4) | (b >> 28));
104-
b += a;
105-
}
106-
107-
static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
108-
{
109-
// Taken from lookup3, by Bob Jenkins.
110-
c ^= b;
111-
c -= ((b << 14) | (b >> 18));
112-
a ^= c;
113-
a -= ((c << 11) | (c >> 21));
114-
b ^= a;
115-
b -= ((a << 25) | (a >> 7));
116-
c ^= b;
117-
c -= ((b << 16) | (b >> 16));
118-
a ^= c;
119-
a -= ((c << 4) | (c >> 28));
120-
b ^= a;
121-
b -= ((a << 14) | (a >> 18));
122-
c ^= b;
123-
c -= ((b << 24) | (b >> 8));
124-
}
125-
126-
uint64_t uint256::GetHash(const uint256& salt) const
127-
{
128-
uint32_t a, b, c;
129-
const uint32_t *pn = (const uint32_t*)data;
130-
const uint32_t *salt_pn = (const uint32_t*)salt.data;
131-
a = b = c = 0xdeadbeef + WIDTH;
132-
133-
a += pn[0] ^ salt_pn[0];
134-
b += pn[1] ^ salt_pn[1];
135-
c += pn[2] ^ salt_pn[2];
136-
HashMix(a, b, c);
137-
a += pn[3] ^ salt_pn[3];
138-
b += pn[4] ^ salt_pn[4];
139-
c += pn[5] ^ salt_pn[5];
140-
HashMix(a, b, c);
141-
a += pn[6] ^ salt_pn[6];
142-
b += pn[7] ^ salt_pn[7];
143-
HashFinal(a, b, c);
144-
145-
return ((((uint64_t)b) << 32) | c);
146-
}

src/uint256.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,6 @@ class uint256 : public base_blob<256> {
140140
{
141141
return ReadLE64(data);
142142
}
143-
144-
/** A more secure, salted hash function.
145-
* @note This hash is not stable between little and big endian.
146-
*/
147-
uint64_t GetHash(const uint256& salt) const;
148143
};
149144

150145
/* uint256 from const char *.

0 commit comments

Comments
 (0)