Merge pull request #4933

20e01b1 Apply clang-format on some infrequently-updated files (Pieter Wuille)
This commit is contained in:
Pieter Wuille 2014-09-21 01:03:32 +02:00
commit 934b153a2c
No known key found for this signature in database
GPG Key ID: 8F653255C87992E0
30 changed files with 845 additions and 742 deletions

View File

@ -64,8 +64,10 @@ double CAddrInfo::GetChance(int64_t nNow) const
int64_t nSinceLastSeen = nNow - nTime; int64_t nSinceLastSeen = nNow - nTime;
int64_t nSinceLastTry = nNow - nLastTry; int64_t nSinceLastTry = nNow - nLastTry;
if (nSinceLastSeen < 0) nSinceLastSeen = 0; if (nSinceLastSeen < 0)
if (nSinceLastTry < 0) nSinceLastTry = 0; nSinceLastSeen = 0;
if (nSinceLastTry < 0)
nSinceLastTry = 0;
fChance *= 600.0 / (600.0 + nSinceLastSeen); fChance *= 600.0 / (600.0 + nSinceLastSeen);
@ -133,8 +135,7 @@ int CAddrMan::SelectTried(int nKBucket)
// find the least recently tried among them // find the least recently tried among them
int64_t nOldest = -1; int64_t nOldest = -1;
int nOldestPos = -1; int nOldestPos = -1;
for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) {
{
int nPos = GetRandInt(vTried.size() - i) + i; int nPos = GetRandInt(vTried.size() - i) + i;
int nTemp = vTried[nPos]; int nTemp = vTried[nPos];
vTried[nPos] = vTried[i]; vTried[nPos] = vTried[i];
@ -155,14 +156,11 @@ int CAddrMan::ShrinkNew(int nUBucket)
std::set<int>& vNew = vvNew[nUBucket]; std::set<int>& vNew = vvNew[nUBucket];
// first look for deletable items // first look for deletable items
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) {
{
assert(mapInfo.count(*it)); assert(mapInfo.count(*it));
CAddrInfo& info = mapInfo[*it]; CAddrInfo& info = mapInfo[*it];
if (info.IsTerrible()) if (info.IsTerrible()) {
{ if (--info.nRefCount == 0) {
if (--info.nRefCount == 0)
{
SwapRandom(info.nRandomPos, vRandom.size() - 1); SwapRandom(info.nRandomPos, vRandom.size() - 1);
vRandom.pop_back(); vRandom.pop_back();
mapAddr.erase(info); mapAddr.erase(info);
@ -178,10 +176,8 @@ int CAddrMan::ShrinkNew(int nUBucket)
int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())}; int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())};
int nI = 0; int nI = 0;
int nOldest = -1; int nOldest = -1;
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) {
{ if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) {
if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3])
{
assert(nOldest == -1 || mapInfo.count(*it) == 1); assert(nOldest == -1 || mapInfo.count(*it) == 1);
if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime) if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime)
nOldest = *it; nOldest = *it;
@ -190,8 +186,7 @@ int CAddrMan::ShrinkNew(int nUBucket)
} }
assert(mapInfo.count(nOldest) == 1); assert(mapInfo.count(nOldest) == 1);
CAddrInfo& info = mapInfo[nOldest]; CAddrInfo& info = mapInfo[nOldest];
if (--info.nRefCount == 0) if (--info.nRefCount == 0) {
{
SwapRandom(info.nRandomPos, vRandom.size() - 1); SwapRandom(info.nRandomPos, vRandom.size() - 1);
vRandom.pop_back(); vRandom.pop_back();
mapAddr.erase(info); mapAddr.erase(info);
@ -208,8 +203,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
assert(vvNew[nOrigin].count(nId) == 1); assert(vvNew[nOrigin].count(nId) == 1);
// remove the entry from all new buckets // remove the entry from all new buckets
for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++) for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++) {
{
if ((*it).erase(nId)) if ((*it).erase(nId))
info.nRefCount--; info.nRefCount--;
} }
@ -222,8 +216,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
std::vector<int>& vTried = vvTried[nKBucket]; std::vector<int>& vTried = vvTried[nKBucket];
// first check whether there is place to just add it // first check whether there is place to just add it
if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) {
{
vTried.push_back(nId); vTried.push_back(nId);
nTried++; nTried++;
info.fInTried = true; info.fInTried = true;
@ -245,8 +238,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
// do not update nTried, as we are going to move something else there immediately // do not update nTried, as we are going to move something else there immediately
// check whether there is place in that one, // check whether there is place in that one,
if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) {
{
// if so, move it back there // if so, move it back there
vNew.insert(vTried[nPos]); vNew.insert(vTried[nPos]);
} else { } else {
@ -289,12 +281,10 @@ void CAddrMan::Good_(const CService &addr, int64_t nTime)
// find a bucket it is in now // find a bucket it is in now
int nRnd = GetRandInt(vvNew.size()); int nRnd = GetRandInt(vvNew.size());
int nUBucket = -1; int nUBucket = -1;
for (unsigned int n = 0; n < vvNew.size(); n++) for (unsigned int n = 0; n < vvNew.size(); n++) {
{
int nB = (n + nRnd) % vvNew.size(); int nB = (n + nRnd) % vvNew.size();
std::set<int>& vNew = vvNew[nB]; std::set<int>& vNew = vvNew[nB];
if (vNew.count(nId)) if (vNew.count(nId)) {
{
nUBucket = nB; nUBucket = nB;
break; break;
} }
@ -302,7 +292,8 @@ void CAddrMan::Good_(const CService &addr, int64_t nTime)
// if no bucket is found, something bad happened; // if no bucket is found, something bad happened;
// TODO: maybe re-add the node, but for now, just bail out // TODO: maybe re-add the node, but for now, just bail out
if (nUBucket == -1) return; if (nUBucket == -1)
return;
LogPrint("addrman", "Moving %s to tried\n", addr.ToString()); LogPrint("addrman", "Moving %s to tried\n", addr.ToString());
@ -319,8 +310,7 @@ bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimeP
int nId; int nId;
CAddrInfo* pinfo = Find(addr, &nId); CAddrInfo* pinfo = Find(addr, &nId);
if (pinfo) if (pinfo) {
{
// periodically update nTime // periodically update nTime
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
@ -357,8 +347,7 @@ bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimeP
int nUBucket = pinfo->GetNewBucket(nKey, source); int nUBucket = pinfo->GetNewBucket(nKey, source);
std::set<int>& vNew = vvNew[nUBucket]; std::set<int>& vNew = vvNew[nUBucket];
if (!vNew.count(nId)) if (!vNew.count(nId)) {
{
pinfo->nRefCount++; pinfo->nRefCount++;
if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE) if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE)
ShrinkNew(nUBucket); ShrinkNew(nUBucket);
@ -393,15 +382,14 @@ CAddress CAddrMan::Select_(int nUnkBias)
double nCorTried = sqrt(nTried) * (100.0 - nUnkBias); double nCorTried = sqrt(nTried) * (100.0 - nUnkBias);
double nCorNew = sqrt(nNew) * nUnkBias; double nCorNew = sqrt(nNew) * nUnkBias;
if ((nCorTried + nCorNew)*GetRandInt(1<<30)/(1<<30) < nCorTried) if ((nCorTried + nCorNew) * GetRandInt(1 << 30) / (1 << 30) < nCorTried) {
{
// use a tried node // use a tried node
double fChanceFactor = 1.0; double fChanceFactor = 1.0;
while(1) while (1) {
{
int nKBucket = GetRandInt(vvTried.size()); int nKBucket = GetRandInt(vvTried.size());
std::vector<int>& vTried = vvTried[nKBucket]; std::vector<int>& vTried = vvTried[nKBucket];
if (vTried.size() == 0) continue; if (vTried.size() == 0)
continue;
int nPos = GetRandInt(vTried.size()); int nPos = GetRandInt(vTried.size());
assert(mapInfo.count(vTried[nPos]) == 1); assert(mapInfo.count(vTried[nPos]) == 1);
CAddrInfo& info = mapInfo[vTried[nPos]]; CAddrInfo& info = mapInfo[vTried[nPos]];
@ -412,11 +400,11 @@ CAddress CAddrMan::Select_(int nUnkBias)
} else { } else {
// use a new node // use a new node
double fChanceFactor = 1.0; double fChanceFactor = 1.0;
while(1) while (1) {
{
int nUBucket = GetRandInt(vvNew.size()); int nUBucket = GetRandInt(vvNew.size());
std::set<int>& vNew = vvNew[nUBucket]; std::set<int>& vNew = vvNew[nUBucket];
if (vNew.size() == 0) continue; if (vNew.size() == 0)
continue;
int nPos = GetRandInt(vNew.size()); int nPos = GetRandInt(vNew.size());
std::set<int>::iterator it = vNew.begin(); std::set<int>::iterator it = vNew.begin();
while (nPos--) while (nPos--)
@ -436,55 +424,63 @@ int CAddrMan::Check_()
std::set<int> setTried; std::set<int> setTried;
std::map<int, int> mapNew; std::map<int, int> mapNew;
if (vRandom.size() != nTried + nNew) return -7; if (vRandom.size() != nTried + nNew)
return -7;
for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
{
int n = (*it).first; int n = (*it).first;
CAddrInfo& info = (*it).second; CAddrInfo& info = (*it).second;
if (info.fInTried) if (info.fInTried) {
{ if (!info.nLastSuccess)
return -1;
if (!info.nLastSuccess) return -1; if (info.nRefCount)
if (info.nRefCount) return -2; return -2;
setTried.insert(n); setTried.insert(n);
} else { } else {
if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return -3; if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
if (!info.nRefCount) return -4; return -3;
if (!info.nRefCount)
return -4;
mapNew[n] = info.nRefCount; mapNew[n] = info.nRefCount;
} }
if (mapAddr[info] != n) return -5; if (mapAddr[info] != n)
if (info.nRandomPos<0 || info.nRandomPos>=vRandom.size() || vRandom[info.nRandomPos] != n) return -14; return -5;
if (info.nLastTry < 0) return -6; if (info.nRandomPos < 0 || info.nRandomPos >= vRandom.size() || vRandom[info.nRandomPos] != n)
if (info.nLastSuccess < 0) return -8; return -14;
if (info.nLastTry < 0)
return -6;
if (info.nLastSuccess < 0)
return -8;
} }
if (setTried.size() != nTried) return -9; if (setTried.size() != nTried)
if (mapNew.size() != nNew) return -10; return -9;
if (mapNew.size() != nNew)
return -10;
for (int n=0; n<vvTried.size(); n++) for (int n = 0; n < vvTried.size(); n++) {
{
std::vector<int>& vTried = vvTried[n]; std::vector<int>& vTried = vvTried[n];
for (std::vector<int>::iterator it = vTried.begin(); it != vTried.end(); it++) for (std::vector<int>::iterator it = vTried.begin(); it != vTried.end(); it++) {
{ if (!setTried.count(*it))
if (!setTried.count(*it)) return -11; return -11;
setTried.erase(*it); setTried.erase(*it);
} }
} }
for (int n=0; n<vvNew.size(); n++) for (int n = 0; n < vvNew.size(); n++) {
{
std::set<int>& vNew = vvNew[n]; std::set<int>& vNew = vvNew[n];
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) {
{ if (!mapNew.count(*it))
if (!mapNew.count(*it)) return -12; return -12;
if (--mapNew[*it] == 0) if (--mapNew[*it] == 0)
mapNew.erase(*it); mapNew.erase(*it);
} }
} }
if (setTried.size()) return -13; if (setTried.size())
if (mapNew.size()) return -15; return -13;
if (mapNew.size())
return -15;
return 0; return 0;
} }
@ -497,8 +493,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr)
nNodes = ADDRMAN_GETADDR_MAX; nNodes = ADDRMAN_GETADDR_MAX;
// gather a list of random nodes, skipping those of low quality // gather a list of random nodes, skipping those of low quality
for (unsigned int n = 0; n < vRandom.size(); n++) for (unsigned int n = 0; n < vRandom.size(); n++) {
{
if (vAddr.size() >= nNodes) if (vAddr.size() >= nNodes)
break; break;

View File

@ -64,4 +64,3 @@ bool MemoryPageLocker::Unlock(const void *addr, size_t len)
LockedPageManager::LockedPageManager() : LockedPageManagerBase<MemoryPageLocker>(GetSystemPageSize()) LockedPageManager::LockedPageManager() : LockedPageManagerBase<MemoryPageLocker>(GetSystemPageSize())
{ {
} }

View File

@ -26,11 +26,11 @@
* small objects that span up to a few pages, mostly smaller than a page. To support large allocations, * small objects that span up to a few pages, mostly smaller than a page. To support large allocations,
* something like an interval tree would be the preferred data structure. * something like an interval tree would be the preferred data structure.
*/ */
template <class Locker> class LockedPageManagerBase template <class Locker>
class LockedPageManagerBase
{ {
public: public:
LockedPageManagerBase(size_t page_size): LockedPageManagerBase(size_t page_size) : page_size(page_size)
page_size(page_size)
{ {
// Determine bitmask for extracting page from address // Determine bitmask for extracting page from address
assert(!(page_size & (page_size - 1))); // size must be power of two assert(!(page_size & (page_size - 1))); // size must be power of two
@ -47,19 +47,18 @@ public:
void LockRange(void* p, size_t size) void LockRange(void* p, size_t size)
{ {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
if(!size) return; if (!size)
return;
const size_t base_addr = reinterpret_cast<size_t>(p); const size_t base_addr = reinterpret_cast<size_t>(p);
const size_t start_page = base_addr & page_mask; const size_t start_page = base_addr & page_mask;
const size_t end_page = (base_addr + size - 1) & page_mask; const size_t end_page = (base_addr + size - 1) & page_mask;
for(size_t page = start_page; page <= end_page; page += page_size) for (size_t page = start_page; page <= end_page; page += page_size) {
{
Histogram::iterator it = histogram.find(page); Histogram::iterator it = histogram.find(page);
if (it == histogram.end()) // Newly locked page if (it == histogram.end()) // Newly locked page
{ {
locker.Lock(reinterpret_cast<void*>(page), page_size); locker.Lock(reinterpret_cast<void*>(page), page_size);
histogram.insert(std::make_pair(page, 1)); histogram.insert(std::make_pair(page, 1));
} } else // Page was already locked; increase counter
else // Page was already locked; increase counter
{ {
it->second += 1; it->second += 1;
} }
@ -70,12 +69,12 @@ public:
void UnlockRange(void* p, size_t size) void UnlockRange(void* p, size_t size)
{ {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
if(!size) return; if (!size)
return;
const size_t base_addr = reinterpret_cast<size_t>(p); const size_t base_addr = reinterpret_cast<size_t>(p);
const size_t start_page = base_addr & page_mask; const size_t start_page = base_addr & page_mask;
const size_t end_page = (base_addr + size - 1) & page_mask; const size_t end_page = (base_addr + size - 1) & page_mask;
for(size_t page = start_page; page <= end_page; page += page_size) for (size_t page = start_page; page <= end_page; page += page_size) {
{
Histogram::iterator it = histogram.find(page); Histogram::iterator it = histogram.find(page);
assert(it != histogram.end()); // Cannot unlock an area that was not locked assert(it != histogram.end()); // Cannot unlock an area that was not locked
// Decrease counter for page, when it is zero, the page will be unlocked // Decrease counter for page, when it is zero, the page will be unlocked
@ -165,11 +164,15 @@ private:
// Functions for directly locking/unlocking memory objects. // Functions for directly locking/unlocking memory objects.
// Intended for non-dynamically allocated structures. // Intended for non-dynamically allocated structures.
// //
template<typename T> void LockObject(const T &t) { template <typename T>
void LockObject(const T& t)
{
LockedPageManager::Instance().LockRange((void*)(&t), sizeof(T)); LockedPageManager::Instance().LockRange((void*)(&t), sizeof(T));
} }
template<typename T> void UnlockObject(const T &t) { template <typename T>
void UnlockObject(const T& t)
{
OPENSSL_cleanse((void*)(&t), sizeof(T)); OPENSSL_cleanse((void*)(&t), sizeof(T));
LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T)); LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T));
} }
@ -179,8 +182,7 @@ template<typename T> void UnlockObject(const T &t) {
// out of memory and clears its contents before deletion. // out of memory and clears its contents before deletion.
// //
template <typename T> template <typename T>
struct secure_allocator : public std::allocator<T> struct secure_allocator : public std::allocator<T> {
{
// MSVC8 default copy constructor is broken // MSVC8 default copy constructor is broken
typedef std::allocator<T> base; typedef std::allocator<T> base;
typedef typename base::size_type size_type; typedef typename base::size_type size_type;
@ -193,10 +195,14 @@ struct secure_allocator : public std::allocator<T>
secure_allocator() throw() {} secure_allocator() throw() {}
secure_allocator(const secure_allocator& a) throw() : base(a) {} secure_allocator(const secure_allocator& a) throw() : base(a) {}
template <typename U> template <typename U>
secure_allocator(const secure_allocator<U>& a) throw() : base(a) {} secure_allocator(const secure_allocator<U>& a) throw() : base(a)
{
}
~secure_allocator() throw() {} ~secure_allocator() throw() {}
template<typename _Other> struct rebind template <typename _Other>
{ typedef secure_allocator<_Other> other; }; struct rebind {
typedef secure_allocator<_Other> other;
};
T* allocate(std::size_t n, const void* hint = 0) T* allocate(std::size_t n, const void* hint = 0)
{ {
@ -209,8 +215,7 @@ struct secure_allocator : public std::allocator<T>
void deallocate(T* p, std::size_t n) void deallocate(T* p, std::size_t n)
{ {
if (p != NULL) if (p != NULL) {
{
OPENSSL_cleanse(p, sizeof(T) * n); OPENSSL_cleanse(p, sizeof(T) * n);
LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n); LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
} }
@ -223,8 +228,7 @@ struct secure_allocator : public std::allocator<T>
// Allocator that clears its contents before deletion. // Allocator that clears its contents before deletion.
// //
template <typename T> template <typename T>
struct zero_after_free_allocator : public std::allocator<T> struct zero_after_free_allocator : public std::allocator<T> {
{
// MSVC8 default copy constructor is broken // MSVC8 default copy constructor is broken
typedef std::allocator<T> base; typedef std::allocator<T> base;
typedef typename base::size_type size_type; typedef typename base::size_type size_type;
@ -237,10 +241,14 @@ struct zero_after_free_allocator : public std::allocator<T>
zero_after_free_allocator() throw() {} zero_after_free_allocator() throw() {}
zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
template <typename U> template <typename U>
zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {} zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a)
{
}
~zero_after_free_allocator() throw() {} ~zero_after_free_allocator() throw() {}
template<typename _Other> struct rebind template <typename _Other>
{ typedef zero_after_free_allocator<_Other> other; }; struct rebind {
typedef zero_after_free_allocator<_Other> other;
};
void deallocate(T* p, std::size_t n) void deallocate(T* p, std::size_t n)
{ {

View File

@ -18,7 +18,8 @@
/* All alphanumeric characters except for "0", "I", "O", and "l" */ /* All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
bool DecodeBase58(const char *psz, std::vector<unsigned char>& vch) { bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
{
// Skip leading spaces. // Skip leading spaces.
while (*psz && isspace(*psz)) while (*psz && isspace(*psz))
psz++; psz++;
@ -63,7 +64,8 @@ bool DecodeBase58(const char *psz, std::vector<unsigned char>& vch) {
return true; return true;
} }
std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) { std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{
// Skip & count leading zeroes. // Skip & count leading zeroes.
int zeroes = 0; int zeroes = 0;
while (pbegin != pend && *pbegin == 0) { while (pbegin != pend && *pbegin == 0) {
@ -97,15 +99,18 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
return str; return str;
} }
std::string EncodeBase58(const std::vector<unsigned char>& vch) { std::string EncodeBase58(const std::vector<unsigned char>& vch)
{
return EncodeBase58(&vch[0], &vch[0] + vch.size()); return EncodeBase58(&vch[0], &vch[0] + vch.size());
} }
bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet) { bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
{
return DecodeBase58(str.c_str(), vchRet); return DecodeBase58(str.c_str(), vchRet);
} }
std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) { std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
{
// add 4-byte hash check to the end // add 4-byte hash check to the end
std::vector<unsigned char> vch(vchIn); std::vector<unsigned char> vch(vchIn);
uint256 hash = Hash(vch.begin(), vch.end()); uint256 hash = Hash(vch.begin(), vch.end());
@ -113,17 +118,16 @@ std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) {
return EncodeBase58(vch); return EncodeBase58(vch);
} }
bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet) { bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
if (!DecodeBase58(psz, vchRet) ||
(vchRet.size() < 4))
{ {
if (!DecodeBase58(psz, vchRet) ||
(vchRet.size() < 4)) {
vchRet.clear(); vchRet.clear();
return false; return false;
} }
// re-calculate the checksum, insure it matches the included 4-byte checksum // re-calculate the checksum, insure it matches the included 4-byte checksum
uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4); uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4);
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) {
{
vchRet.clear(); vchRet.clear();
return false; return false;
} }
@ -131,27 +135,32 @@ bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet) {
return true; return true;
} }
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet) { bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
{
return DecodeBase58Check(str.c_str(), vchRet); return DecodeBase58Check(str.c_str(), vchRet);
} }
CBase58Data::CBase58Data() { CBase58Data::CBase58Data()
{
vchVersion.clear(); vchVersion.clear();
vchData.clear(); vchData.clear();
} }
void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize) { void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize)
{
vchVersion = vchVersionIn; vchVersion = vchVersionIn;
vchData.resize(nSize); vchData.resize(nSize);
if (!vchData.empty()) if (!vchData.empty())
memcpy(&vchData[0], pdata, nSize); memcpy(&vchData[0], pdata, nSize);
} }
void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend) { void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
{
SetData(vchVersionIn, (void*)pbegin, pend - pbegin); SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
} }
bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) { bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
{
std::vector<unsigned char> vchTemp; std::vector<unsigned char> vchTemp;
bool rc58 = DecodeBase58Check(psz, vchTemp); bool rc58 = DecodeBase58Check(psz, vchTemp);
if ((!rc58) || (vchTemp.size() < nVersionBytes)) { if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
@ -167,29 +176,38 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) {
return true; return true;
} }
bool CBase58Data::SetString(const std::string& str) { bool CBase58Data::SetString(const std::string& str)
{
return SetString(str.c_str()); return SetString(str.c_str());
} }
std::string CBase58Data::ToString() const { std::string CBase58Data::ToString() const
{
std::vector<unsigned char> vch = vchVersion; std::vector<unsigned char> vch = vchVersion;
vch.insert(vch.end(), vchData.begin(), vchData.end()); vch.insert(vch.end(), vchData.begin(), vchData.end());
return EncodeBase58Check(vch); return EncodeBase58Check(vch);
} }
int CBase58Data::CompareTo(const CBase58Data& b58) const { int CBase58Data::CompareTo(const CBase58Data& b58) const
if (vchVersion < b58.vchVersion) return -1; {
if (vchVersion > b58.vchVersion) return 1; if (vchVersion < b58.vchVersion)
if (vchData < b58.vchData) return -1; return -1;
if (vchData > b58.vchData) return 1; if (vchVersion > b58.vchVersion)
return 1;
if (vchData < b58.vchData)
return -1;
if (vchData > b58.vchData)
return 1;
return 0; return 0;
} }
namespace { namespace
{
class CBitcoinAddressVisitor : public boost::static_visitor<bool> { class CBitcoinAddressVisitor : public boost::static_visitor<bool>
{
private: private:
CBitcoinAddress* addr; CBitcoinAddress* addr;
public: public:
CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {} CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {}
@ -200,32 +218,38 @@ namespace {
} // anon namespace } // anon namespace
bool CBitcoinAddress::Set(const CKeyID &id) { bool CBitcoinAddress::Set(const CKeyID& id)
{
SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20); SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
return true; return true;
} }
bool CBitcoinAddress::Set(const CScriptID &id) { bool CBitcoinAddress::Set(const CScriptID& id)
{
SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20); SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
return true; return true;
} }
bool CBitcoinAddress::Set(const CTxDestination &dest) { bool CBitcoinAddress::Set(const CTxDestination& dest)
{
return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
} }
bool CBitcoinAddress::IsValid() const { bool CBitcoinAddress::IsValid() const
{
return IsValid(Params()); return IsValid(Params());
} }
bool CBitcoinAddress::IsValid(const CChainParams &params) const { bool CBitcoinAddress::IsValid(const CChainParams& params) const
{
bool fCorrectSize = vchData.size() == 20; bool fCorrectSize = vchData.size() == 20;
bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) || bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
return fCorrectSize && fKnownVersion; return fCorrectSize && fKnownVersion;
} }
CTxDestination CBitcoinAddress::Get() const { CTxDestination CBitcoinAddress::Get() const
{
if (!IsValid()) if (!IsValid())
return CNoDestination(); return CNoDestination();
uint160 id; uint160 id;
@ -238,7 +262,8 @@ CTxDestination CBitcoinAddress::Get() const {
return CNoDestination(); return CNoDestination();
} }
bool CBitcoinAddress::GetKeyID(CKeyID &keyID) const { bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
{
if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return false; return false;
uint160 id; uint160 id;
@ -247,33 +272,39 @@ bool CBitcoinAddress::GetKeyID(CKeyID &keyID) const {
return true; return true;
} }
bool CBitcoinAddress::IsScript() const { bool CBitcoinAddress::IsScript() const
{
return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
} }
void CBitcoinSecret::SetKey(const CKey& vchSecret) { void CBitcoinSecret::SetKey(const CKey& vchSecret)
{
assert(vchSecret.IsValid()); assert(vchSecret.IsValid());
SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size()); SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
if (vchSecret.IsCompressed()) if (vchSecret.IsCompressed())
vchData.push_back(1); vchData.push_back(1);
} }
CKey CBitcoinSecret::GetKey() { CKey CBitcoinSecret::GetKey()
{
CKey ret; CKey ret;
ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1); ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1);
return ret; return ret;
} }
bool CBitcoinSecret::IsValid() const { bool CBitcoinSecret::IsValid() const
{
bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1); bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY); bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
return fExpectedFormat && fCorrectVersion; return fExpectedFormat && fCorrectVersion;
} }
bool CBitcoinSecret::SetString(const char* pszSecret) { bool CBitcoinSecret::SetString(const char* pszSecret)
{
return CBase58Data::SetString(pszSecret) && IsValid(); return CBase58Data::SetString(pszSecret) && IsValid();
} }
bool CBitcoinSecret::SetString(const std::string& strSecret) { bool CBitcoinSecret::SetString(const std::string& strSecret)
{
return SetString(strSecret.c_str()); return SetString(strSecret.c_str());
} }

View File

@ -17,9 +17,11 @@ using namespace boost::assign;
// Main network // Main network
// //
class CBaseMainParams : public CBaseChainParams { class CBaseMainParams : public CBaseChainParams
{
public: public:
CBaseMainParams() { CBaseMainParams()
{
networkID = CBaseChainParams::MAIN; networkID = CBaseChainParams::MAIN;
nRPCPort = 8332; nRPCPort = 8332;
} }
@ -29,9 +31,11 @@ static CBaseMainParams mainParams;
// //
// Testnet (v3) // Testnet (v3)
// //
class CBaseTestNetParams : public CBaseMainParams { class CBaseTestNetParams : public CBaseMainParams
{
public: public:
CBaseTestNetParams() { CBaseTestNetParams()
{
networkID = CBaseChainParams::TESTNET; networkID = CBaseChainParams::TESTNET;
nRPCPort = 18332; nRPCPort = 18332;
strDataDir = "testnet3"; strDataDir = "testnet3";
@ -42,9 +46,11 @@ static CBaseTestNetParams testNetParams;
// //
// Regression test // Regression test
// //
class CBaseRegTestParams : public CBaseTestNetParams { class CBaseRegTestParams : public CBaseTestNetParams
{
public: public:
CBaseRegTestParams() { CBaseRegTestParams()
{
networkID = CBaseChainParams::REGTEST; networkID = CBaseChainParams::REGTEST;
strDataDir = "regtest"; strDataDir = "regtest";
} }
@ -53,12 +59,14 @@ static CBaseRegTestParams regTestParams;
static CBaseChainParams* pCurrentBaseParams = 0; static CBaseChainParams* pCurrentBaseParams = 0;
const CBaseChainParams &BaseParams() { const CBaseChainParams& BaseParams()
{
assert(pCurrentBaseParams); assert(pCurrentBaseParams);
return *pCurrentBaseParams; return *pCurrentBaseParams;
} }
void SelectBaseParams(CBaseChainParams::Network network) { void SelectBaseParams(CBaseChainParams::Network network)
{
switch (network) { switch (network) {
case CBaseChainParams::MAIN: case CBaseChainParams::MAIN:
pCurrentBaseParams = &mainParams; pCurrentBaseParams = &mainParams;
@ -75,7 +83,8 @@ void SelectBaseParams(CBaseChainParams::Network network) {
} }
} }
bool SelectBaseParamsFromCommandLine() { bool SelectBaseParamsFromCommandLine()
{
bool fRegTest = GetBoolArg("-regtest", false); bool fRegTest = GetBoolArg("-regtest", false);
bool fTestNet = GetBoolArg("-testnet", false); bool fTestNet = GetBoolArg("-testnet", false);
@ -93,6 +102,7 @@ bool SelectBaseParamsFromCommandLine() {
return true; return true;
} }
bool AreBaseParamsConfigured() { bool AreBaseParamsConfigured()
{
return pCurrentBaseParams != NULL; return pCurrentBaseParams != NULL;
} }

View File

@ -26,6 +26,7 @@ public:
const std::string& DataDir() const { return strDataDir; } const std::string& DataDir() const { return strDataDir; }
int RPCPort() const { return nRPCPort; } int RPCPort() const { return nRPCPort; }
Network NetworkID() const { return networkID; } Network NetworkID() const { return networkID; }
protected: protected:
CBaseChainParams() {} CBaseChainParams() {}

View File

@ -13,8 +13,8 @@ class uint256;
/** Block-chain checkpoints are compiled-in sanity checks. /** Block-chain checkpoints are compiled-in sanity checks.
* They are updated every release or three. * They are updated every release or three.
*/ */
namespace Checkpoints { namespace Checkpoints
{
// Returns true if block passes checkpoint checks // Returns true if block passes checkpoint checks
bool CheckBlock(int nHeight, const uint256& hash); bool CheckBlock(int nHeight, const uint256& hash);

View File

@ -13,7 +13,8 @@
#include <boost/thread/locks.hpp> #include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
template<typename T> class CCheckQueueControl; template <typename T>
class CCheckQueueControl;
/** Queue for verifications that have to be performed. /** Queue for verifications that have to be performed.
* The verifications are represented by a type T, which must provide an * The verifications are represented by a type T, which must provide an
@ -24,7 +25,9 @@ template<typename T> class CCheckQueueControl;
* the master is done adding work, it temporarily joins the worker pool * the master is done adding work, it temporarily joins the worker pool
* as an N'th worker, until all jobs are done. * as an N'th worker, until all jobs are done.
*/ */
template<typename T> class CCheckQueue { template <typename T>
class CCheckQueue
{
private: private:
// Mutex to protect the inner state // Mutex to protect the inner state
boost::mutex mutex; boost::mutex mutex;
@ -60,7 +63,8 @@ private:
unsigned int nBatchSize; unsigned int nBatchSize;
// Internal function that does bulk of the verification work. // Internal function that does bulk of the verification work.
bool Loop(bool fMaster = false) { bool Loop(bool fMaster = false)
{
boost::condition_variable& cond = fMaster ? condMaster : condWorker; boost::condition_variable& cond = fMaster ? condMaster : condWorker;
std::vector<T> vChecks; std::vector<T> vChecks;
vChecks.reserve(nBatchSize); vChecks.reserve(nBatchSize);
@ -121,21 +125,23 @@ private:
public: public:
// Create a new check queue // Create a new check queue
CCheckQueue(unsigned int nBatchSizeIn) : CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {}
nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {}
// Worker thread // Worker thread
void Thread() { void Thread()
{
Loop(); Loop();
} }
// Wait until execution finishes, and return whether all evaluations where succesful. // Wait until execution finishes, and return whether all evaluations where succesful.
bool Wait() { bool Wait()
{
return Loop(true); return Loop(true);
} }
// Add a batch of checks to the queue // Add a batch of checks to the queue
void Add(std::vector<T> &vChecks) { void Add(std::vector<T>& vChecks)
{
boost::unique_lock<boost::mutex> lock(mutex); boost::unique_lock<boost::mutex> lock(mutex);
BOOST_FOREACH (T& check, vChecks) { BOOST_FOREACH (T& check, vChecks) {
queue.push_back(T()); queue.push_back(T());
@ -148,7 +154,8 @@ public:
condWorker.notify_all(); condWorker.notify_all();
} }
~CCheckQueue() { ~CCheckQueue()
{
} }
friend class CCheckQueueControl<T>; friend class CCheckQueueControl<T>;
@ -157,13 +164,16 @@ public:
/** RAII-style controller object for a CCheckQueue that guarantees the passed /** RAII-style controller object for a CCheckQueue that guarantees the passed
* queue is finished before continuing. * queue is finished before continuing.
*/ */
template<typename T> class CCheckQueueControl { template <typename T>
class CCheckQueueControl
{
private: private:
CCheckQueue<T>* pqueue; CCheckQueue<T>* pqueue;
bool fDone; bool fDone;
public: public:
CCheckQueueControl(CCheckQueue<T> *pqueueIn) : pqueue(pqueueIn), fDone(false) { CCheckQueueControl(CCheckQueue<T>* pqueueIn) : pqueue(pqueueIn), fDone(false)
{
// passed queue is supposed to be unused, or NULL // passed queue is supposed to be unused, or NULL
if (pqueue != NULL) { if (pqueue != NULL) {
assert(pqueue->nTotal == pqueue->nIdle); assert(pqueue->nTotal == pqueue->nIdle);
@ -172,7 +182,8 @@ public:
} }
} }
bool Wait() { bool Wait()
{
if (pqueue == NULL) if (pqueue == NULL)
return true; return true;
bool fRet = pqueue->Wait(); bool fRet = pqueue->Wait();
@ -180,12 +191,14 @@ public:
return fRet; return fRet;
} }
void Add(std::vector<T> &vChecks) { void Add(std::vector<T>& vChecks)
{
if (pqueue != NULL) if (pqueue != NULL)
pqueue->Add(vChecks); pqueue->Add(vChecks);
} }
~CCheckQueueControl() { ~CCheckQueueControl()
{
if (!fDone) if (!fDone)
Wait(); Wait();
} }

View File

@ -57,7 +57,6 @@ public:
private: private:
std::set<COutPoint> setSelected; std::set<COutPoint> setSelected;
}; };
#endif // COINCONTROL_H #endif // COINCONTROL_H

View File

@ -30,7 +30,6 @@ using namespace boost;
unsigned int nWalletDBUpdated; unsigned int nWalletDBUpdated;
// //
// CDB // CDB
// //
@ -160,30 +159,27 @@ CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDB
return (fRecovered ? RECOVER_OK : RECOVER_FAIL); return (fRecovered ? RECOVER_OK : RECOVER_FAIL);
} }
bool CDBEnv::Salvage(std::string strFile, bool fAggressive, bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector<CDBEnv::KeyValPair>& vResult)
std::vector<CDBEnv::KeyValPair >& vResult)
{ {
LOCK(cs_db); LOCK(cs_db);
assert(mapFileUseCount.count(strFile) == 0); assert(mapFileUseCount.count(strFile) == 0);
u_int32_t flags = DB_SALVAGE; u_int32_t flags = DB_SALVAGE;
if (fAggressive) flags |= DB_AGGRESSIVE; if (fAggressive)
flags |= DB_AGGRESSIVE;
stringstream strDump; stringstream strDump;
Db db(&dbenv, 0); Db db(&dbenv, 0);
int result = db.verify(strFile.c_str(), NULL, &strDump, flags); int result = db.verify(strFile.c_str(), NULL, &strDump, flags);
if (result == DB_VERIFY_BAD) if (result == DB_VERIFY_BAD) {
{
LogPrintf("CDBEnv::Salvage : Database salvage found errors, all data may not be recoverable.\n"); LogPrintf("CDBEnv::Salvage : Database salvage found errors, all data may not be recoverable.\n");
if (!fAggressive) if (!fAggressive) {
{
LogPrintf("CDBEnv::Salvage : Rerun with aggressive mode to ignore errors and continue.\n"); LogPrintf("CDBEnv::Salvage : Rerun with aggressive mode to ignore errors and continue.\n");
return false; return false;
} }
} }
if (result != 0 && result != DB_VERIFY_BAD) if (result != 0 && result != DB_VERIFY_BAD) {
{
LogPrintf("CDBEnv::Salvage : Database salvage failed with result %d.\n", result); LogPrintf("CDBEnv::Salvage : Database salvage failed with result %d.\n", result);
return false; return false;
} }
@ -201,11 +197,9 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive,
getline(strDump, strLine); // Skip past header getline(strDump, strLine); // Skip past header
std::string keyHex, valueHex; std::string keyHex, valueHex;
while (!strDump.eof() && keyHex != "DATA=END") while (!strDump.eof() && keyHex != "DATA=END") {
{
getline(strDump, keyHex); getline(strDump, keyHex);
if (keyHex != "DATA_END") if (keyHex != "DATA_END") {
{
getline(strDump, valueHex); getline(strDump, valueHex);
vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex))); vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
} }
@ -224,8 +218,7 @@ void CDBEnv::CheckpointLSN(const std::string& strFile)
} }
CDB::CDB(const std::string& strFilename, const char* pszMode) : CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activeTxn(NULL)
pdb(NULL), activeTxn(NULL)
{ {
int ret; int ret;
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
@ -245,13 +238,11 @@ CDB::CDB(const std::string& strFilename, const char* pszMode) :
strFile = strFilename; strFile = strFilename;
++bitdb.mapFileUseCount[strFile]; ++bitdb.mapFileUseCount[strFile];
pdb = bitdb.mapDb[strFile]; pdb = bitdb.mapDb[strFile];
if (pdb == NULL) if (pdb == NULL) {
{
pdb = new Db(&bitdb.dbenv, 0); pdb = new Db(&bitdb.dbenv, 0);
bool fMockDb = bitdb.IsMock(); bool fMockDb = bitdb.IsMock();
if (fMockDb) if (fMockDb) {
{
DbMpoolFile* mpf = pdb->get_mpf(); DbMpoolFile* mpf = pdb->get_mpf();
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
if (ret != 0) if (ret != 0)
@ -265,8 +256,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode) :
nFlags, // Flags nFlags, // Flags
0); 0);
if (ret != 0) if (ret != 0) {
{
delete pdb; delete pdb;
pdb = NULL; pdb = NULL;
--bitdb.mapFileUseCount[strFile]; --bitdb.mapFileUseCount[strFile];
@ -274,8 +264,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode) :
throw runtime_error(strprintf("CDB : Error %d, can't open database %s", ret, strFile)); throw runtime_error(strprintf("CDB : Error %d, can't open database %s", ret, strFile));
} }
if (fCreate && !Exists(string("version"))) if (fCreate && !Exists(string("version"))) {
{
bool fTmp = fReadOnly; bool fTmp = fReadOnly;
fReadOnly = false; fReadOnly = false;
WriteVersion(CLIENT_VERSION); WriteVersion(CLIENT_VERSION);
@ -321,8 +310,7 @@ void CDBEnv::CloseDb(const string& strFile)
{ {
{ {
LOCK(cs_db); LOCK(cs_db);
if (mapDb[strFile] != NULL) if (mapDb[strFile] != NULL) {
{
// Close the database handle // Close the database handle
Db* pdb = mapDb[strFile]; Db* pdb = mapDb[strFile];
pdb->close(0); pdb->close(0);
@ -343,12 +331,10 @@ bool CDBEnv::RemoveDb(const string& strFile)
bool CDB::Rewrite(const string& strFile, const char* pszSkip) bool CDB::Rewrite(const string& strFile, const char* pszSkip)
{ {
while (true) while (true) {
{
{ {
LOCK(bitdb.cs_db); LOCK(bitdb.cs_db);
if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) {
{
// Flush log data to the dat file // Flush log data to the dat file
bitdb.CloseDb(strFile); bitdb.CloseDb(strFile);
bitdb.CheckpointLSN(strFile); bitdb.CheckpointLSN(strFile);
@ -367,26 +353,21 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
DB_BTREE, // Database type DB_BTREE, // Database type
DB_CREATE, // Flags DB_CREATE, // Flags
0); 0);
if (ret > 0) if (ret > 0) {
{
LogPrintf("CDB::Rewrite : Can't create database file %s\n", strFileRes); LogPrintf("CDB::Rewrite : Can't create database file %s\n", strFileRes);
fSuccess = false; fSuccess = false;
} }
Dbc* pcursor = db.GetCursor(); Dbc* pcursor = db.GetCursor();
if (pcursor) if (pcursor)
while (fSuccess) while (fSuccess) {
{
CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
if (ret == DB_NOTFOUND) if (ret == DB_NOTFOUND) {
{
pcursor->close(); pcursor->close();
break; break;
} } else if (ret != 0) {
else if (ret != 0)
{
pcursor->close(); pcursor->close();
fSuccess = false; fSuccess = false;
break; break;
@ -394,8 +375,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
if (pszSkip && if (pszSkip &&
strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
continue; continue;
if (strncmp(&ssKey[0], "\x07version", 8) == 0) if (strncmp(&ssKey[0], "\x07version", 8) == 0) {
{
// Update version: // Update version:
ssValue.clear(); ssValue.clear();
ssValue << CLIENT_VERSION; ssValue << CLIENT_VERSION;
@ -406,8 +386,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
if (ret2 > 0) if (ret2 > 0)
fSuccess = false; fSuccess = false;
} }
if (fSuccess) if (fSuccess) {
{
db.Close(); db.Close();
bitdb.CloseDb(strFile); bitdb.CloseDb(strFile);
if (pdbCopy->close(0)) if (pdbCopy->close(0))
@ -415,8 +394,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
delete pdbCopy; delete pdbCopy;
} }
} }
if (fSuccess) if (fSuccess) {
{
Db dbA(&bitdb.dbenv, 0); Db dbA(&bitdb.dbenv, 0);
if (dbA.remove(strFile.c_str(), NULL, 0)) if (dbA.remove(strFile.c_str(), NULL, 0))
fSuccess = false; fSuccess = false;
@ -445,13 +423,11 @@ void CDBEnv::Flush(bool fShutdown)
{ {
LOCK(cs_db); LOCK(cs_db);
map<string, int>::iterator mi = mapFileUseCount.begin(); map<string, int>::iterator mi = mapFileUseCount.begin();
while (mi != mapFileUseCount.end()) while (mi != mapFileUseCount.end()) {
{
string strFile = (*mi).first; string strFile = (*mi).first;
int nRefCount = (*mi).second; int nRefCount = (*mi).second;
LogPrint("db", "CDBEnv::Flush : Flushing %s (refcount = %d)...\n", strFile, nRefCount); LogPrint("db", "CDBEnv::Flush : Flushing %s (refcount = %d)...\n", strFile, nRefCount);
if (nRefCount == 0) if (nRefCount == 0) {
{
// Move log data to the dat file // Move log data to the dat file
CloseDb(strFile); CloseDb(strFile);
LogPrint("db", "CDBEnv::Flush : %s checkpoint\n", strFile); LogPrint("db", "CDBEnv::Flush : %s checkpoint\n", strFile);
@ -461,16 +437,13 @@ void CDBEnv::Flush(bool fShutdown)
dbenv.lsn_reset(strFile.c_str(), 0); dbenv.lsn_reset(strFile.c_str(), 0);
LogPrint("db", "CDBEnv::Flush : %s closed\n", strFile); LogPrint("db", "CDBEnv::Flush : %s closed\n", strFile);
mapFileUseCount.erase(mi++); mapFileUseCount.erase(mi++);
} } else
else
mi++; mi++;
} }
LogPrint("db", "CDBEnv::Flush : Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); LogPrint("db", "CDBEnv::Flush : Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
if (fShutdown) if (fShutdown) {
{
char** listp; char** listp;
if (mapFileUseCount.empty()) if (mapFileUseCount.empty()) {
{
dbenv.log_archive(&listp, DB_ARCH_REMOVE); dbenv.log_archive(&listp, DB_ARCH_REMOVE);
Close(); Close();
if (!fMockDb) if (!fMockDb)
@ -479,4 +452,3 @@ void CDBEnv::Flush(bool fShutdown)
} }
} }
} }

View File

@ -54,7 +54,9 @@ public:
* This must be called BEFORE strFile is opened. * This must be called BEFORE strFile is opened.
* Returns true if strFile is OK. * Returns true if strFile is OK.
*/ */
enum VerifyResult { VERIFY_OK, RECOVER_OK, RECOVER_FAIL }; enum VerifyResult { VERIFY_OK,
RECOVER_OK,
RECOVER_FAIL };
VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile));
/* /*
* Salvage data from a file that Verify says is bad. * Salvage data from a file that Verify says is bad.
@ -132,8 +134,7 @@ protected:
try { try {
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
ssValue >> value; ssValue >> value;
} } catch (const std::exception&) {
catch (const std::exception &) {
return false; return false;
} }
@ -229,14 +230,12 @@ protected:
{ {
// Read at cursor // Read at cursor
Dbt datKey; Dbt datKey;
if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) {
{
datKey.set_data(&ssKey[0]); datKey.set_data(&ssKey[0]);
datKey.set_size(ssKey.size()); datKey.set_size(ssKey.size());
} }
Dbt datValue; Dbt datValue;
if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) {
{
datValue.set_data(&ssValue[0]); datValue.set_data(&ssValue[0]);
datValue.set_size(ssValue.size()); datValue.set_size(ssValue.size());
} }

View File

@ -18,8 +18,7 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
// body // body
const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4); const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4);
for(int i = -nblocks; i; i++) for (int i = -nblocks; i; i++) {
{
uint32_t k1 = blocks[i]; uint32_t k1 = blocks[i];
k1 *= c1; k1 *= c1;
@ -37,12 +36,17 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
uint32_t k1 = 0; uint32_t k1 = 0;
switch(vDataToHash.size() & 3) switch (vDataToHash.size() & 3) {
{ case 3:
case 3: k1 ^= tail[2] << 16; k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8; case 2:
case 1: k1 ^= tail[0]; k1 ^= tail[1] << 8;
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; case 1:
k1 ^= tail[0];
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
}; };
//---------- //----------

View File

@ -10,7 +10,8 @@
class CWallet; class CWallet;
namespace boost { namespace boost
{
class thread_group; class thread_group;
} // namespace boost } // namespace boost
@ -22,8 +23,7 @@ void Shutdown();
bool AppInit2(boost::thread_group& threadGroup); bool AppInit2(boost::thread_group& threadGroup);
/* The help message mode determines what help message to show */ /* The help message mode determines what help message to show */
enum HelpMessageMode enum HelpMessageMode {
{
HMM_BITCOIND, HMM_BITCOIND,
HMM_BITCOIN_QT HMM_BITCOIN_QT
}; };

View File

@ -39,14 +39,16 @@ public:
}; };
/** An encapsulated public key. */ /** An encapsulated public key. */
class CPubKey { class CPubKey
{
private: private:
// Just store the serialized data. // Just store the serialized data.
// Its length can very cheaply be computed from the first byte. // Its length can very cheaply be computed from the first byte.
unsigned char vch[65]; unsigned char vch[65];
// Compute the length of a pubkey with a given first byte. // Compute the length of a pubkey with a given first byte.
unsigned int static GetLen(unsigned char chHeader) { unsigned int static GetLen(unsigned char chHeader)
{
if (chHeader == 2 || chHeader == 3) if (chHeader == 2 || chHeader == 3)
return 33; return 33;
if (chHeader == 4 || chHeader == 6 || chHeader == 7) if (chHeader == 4 || chHeader == 6 || chHeader == 7)
@ -55,19 +57,22 @@ private:
} }
// Set this key data to be invalid // Set this key data to be invalid
void Invalidate() { void Invalidate()
{
vch[0] = 0xFF; vch[0] = 0xFF;
} }
public: public:
// Construct an invalid public key. // Construct an invalid public key.
CPubKey() { CPubKey()
{
Invalidate(); Invalidate();
} }
// Initialize a public key using begin/end iterators to byte data. // Initialize a public key using begin/end iterators to byte data.
template <typename T> template <typename T>
void Set(const T pbegin, const T pend) { void Set(const T pbegin, const T pend)
{
int len = pend == pbegin ? 0 : GetLen(pbegin[0]); int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
if (len && len == (pend - pbegin)) if (len && len == (pend - pbegin))
memcpy(vch, (unsigned char*)&pbegin[0], len); memcpy(vch, (unsigned char*)&pbegin[0], len);
@ -77,12 +82,14 @@ public:
// Construct a public key using begin/end iterators to byte data. // Construct a public key using begin/end iterators to byte data.
template <typename T> template <typename T>
CPubKey(const T pbegin, const T pend) { CPubKey(const T pbegin, const T pend)
{
Set(pbegin, pend); Set(pbegin, pend);
} }
// Construct a public key from a byte vector. // Construct a public key from a byte vector.
CPubKey(const std::vector<unsigned char> &vch) { CPubKey(const std::vector<unsigned char>& vch)
{
Set(vch.begin(), vch.end()); Set(vch.begin(), vch.end());
} }
@ -93,28 +100,36 @@ public:
const unsigned char& operator[](unsigned int pos) const { return vch[pos]; } const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
// Comparator implementation. // Comparator implementation.
friend bool operator==(const CPubKey &a, const CPubKey &b) { friend bool operator==(const CPubKey& a, const CPubKey& b)
{
return a.vch[0] == b.vch[0] && return a.vch[0] == b.vch[0] &&
memcmp(a.vch, b.vch, a.size()) == 0; memcmp(a.vch, b.vch, a.size()) == 0;
} }
friend bool operator!=(const CPubKey &a, const CPubKey &b) { friend bool operator!=(const CPubKey& a, const CPubKey& b)
{
return !(a == b); return !(a == b);
} }
friend bool operator<(const CPubKey &a, const CPubKey &b) { friend bool operator<(const CPubKey& a, const CPubKey& b)
{
return a.vch[0] < b.vch[0] || return a.vch[0] < b.vch[0] ||
(a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0); (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
} }
// Implement serialization, as if this was a byte vector. // Implement serialization, as if this was a byte vector.
unsigned int GetSerializeSize(int nType, int nVersion) const { unsigned int GetSerializeSize(int nType, int nVersion) const
{
return size() + 1; return size() + 1;
} }
template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const { template <typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const
{
unsigned int len = size(); unsigned int len = size();
::WriteCompactSize(s, len); ::WriteCompactSize(s, len);
s.write((char*)vch, len); s.write((char*)vch, len);
} }
template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) { template <typename Stream>
void Unserialize(Stream& s, int nType, int nVersion)
{
unsigned int len = ::ReadCompactSize(s); unsigned int len = ::ReadCompactSize(s);
if (len <= 65) { if (len <= 65) {
s.read((char*)vch, len); s.read((char*)vch, len);
@ -128,19 +143,22 @@ public:
} }
// Get the KeyID of this public key (hash of its serialization) // Get the KeyID of this public key (hash of its serialization)
CKeyID GetID() const { CKeyID GetID() const
{
return CKeyID(Hash160(vch, vch + size())); return CKeyID(Hash160(vch, vch + size()));
} }
// Get the 256-bit hash of this public key. // Get the 256-bit hash of this public key.
uint256 GetHash() const { uint256 GetHash() const
{
return Hash(vch, vch + size()); return Hash(vch, vch + size());
} }
// Check syntactic correctness. // Check syntactic correctness.
// //
// Note that this is consensus critical as CheckSig() calls it! // Note that this is consensus critical as CheckSig() calls it!
bool IsValid() const { bool IsValid() const
{
return size() > 0; return size() > 0;
} }
@ -148,7 +166,8 @@ public:
bool IsFullyValid() const; bool IsFullyValid() const;
// Check whether this is a compressed public key. // Check whether this is a compressed public key.
bool IsCompressed() const { bool IsCompressed() const
{
return size() == 33; return size() == 33;
} }
@ -172,7 +191,8 @@ public:
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
/** An encapsulated private key. */ /** An encapsulated private key. */
class CKey { class CKey
{
private: private:
// Whether this private key is valid. We check for correctness when modifying the key // Whether this private key is valid. We check for correctness when modifying the key
// data, so fValid should always correspond to the actual state. // data, so fValid should always correspond to the actual state.
@ -186,32 +206,37 @@ private:
// Check whether the 32-byte array pointed to be vch is valid keydata. // Check whether the 32-byte array pointed to be vch is valid keydata.
bool static Check(const unsigned char* vch); bool static Check(const unsigned char* vch);
public:
public:
// Construct an invalid private key. // Construct an invalid private key.
CKey() : fValid(false), fCompressed(false) { CKey() : fValid(false), fCompressed(false)
{
LockObject(vch); LockObject(vch);
} }
// Copy constructor. This is necessary because of memlocking. // Copy constructor. This is necessary because of memlocking.
CKey(const CKey &secret) : fValid(secret.fValid), fCompressed(secret.fCompressed) { CKey(const CKey& secret) : fValid(secret.fValid), fCompressed(secret.fCompressed)
{
LockObject(vch); LockObject(vch);
memcpy(vch, secret.vch, sizeof(vch)); memcpy(vch, secret.vch, sizeof(vch));
} }
// Destructor (again necessary because of memlocking). // Destructor (again necessary because of memlocking).
~CKey() { ~CKey()
{
UnlockObject(vch); UnlockObject(vch);
} }
friend bool operator==(const CKey &a, const CKey &b) { friend bool operator==(const CKey& a, const CKey& b)
{
return a.fCompressed == b.fCompressed && a.size() == b.size() && return a.fCompressed == b.fCompressed && a.size() == b.size() &&
memcmp(&a.vch[0], &b.vch[0], a.size()) == 0; memcmp(&a.vch[0], &b.vch[0], a.size()) == 0;
} }
// Initialize using begin and end iterators to byte data. // Initialize using begin and end iterators to byte data.
template <typename T> template <typename T>
void Set(const T pbegin, const T pend, bool fCompressedIn) { void Set(const T pbegin, const T pend, bool fCompressedIn)
{
if (pend - pbegin != 32) { if (pend - pbegin != 32) {
fValid = false; fValid = false;
return; return;
@ -277,7 +302,8 @@ struct CExtPubKey {
unsigned char vchChainCode[32]; unsigned char vchChainCode[32];
CPubKey pubkey; CPubKey pubkey;
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) { friend bool operator==(const CExtPubKey& a, const CExtPubKey& b)
{
return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild && return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.pubkey == b.pubkey; memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.pubkey == b.pubkey;
} }
@ -294,7 +320,8 @@ struct CExtKey {
unsigned char vchChainCode[32]; unsigned char vchChainCode[32];
CKey key; CKey key;
friend bool operator==(const CExtKey &a, const CExtKey &b) { friend bool operator==(const CExtKey& a, const CExtKey& b)
{
return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild && return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.key == b.key; memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.key == b.key;
} }

View File

@ -12,7 +12,8 @@
#include <leveldb/filter_policy.h> #include <leveldb/filter_policy.h>
#include <memenv.h> #include <memenv.h>
void HandleError(const leveldb::Status &status) throw(leveldb_error) { void HandleError(const leveldb::Status& status) throw(leveldb_error)
{
if (status.ok()) if (status.ok())
return; return;
LogPrintf("%s\n", status.ToString()); LogPrintf("%s\n", status.ToString());
@ -25,7 +26,8 @@ void HandleError(const leveldb::Status &status) throw(leveldb_error) {
throw leveldb_error("Unknown database error"); throw leveldb_error("Unknown database error");
} }
static leveldb::Options GetOptions(size_t nCacheSize) { static leveldb::Options GetOptions(size_t nCacheSize)
{
leveldb::Options options; leveldb::Options options;
options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously
@ -40,7 +42,8 @@ static leveldb::Options GetOptions(size_t nCacheSize) {
return options; return options;
} }
CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe) { CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe)
{
penv = NULL; penv = NULL;
readoptions.verify_checksums = true; readoptions.verify_checksums = true;
iteroptions.verify_checksums = true; iteroptions.verify_checksums = true;
@ -64,7 +67,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path &path, size_t nCa
LogPrintf("Opened LevelDB successfully\n"); LogPrintf("Opened LevelDB successfully\n");
} }
CLevelDBWrapper::~CLevelDBWrapper() { CLevelDBWrapper::~CLevelDBWrapper()
{
delete pdb; delete pdb;
pdb = NULL; pdb = NULL;
delete options.filter_policy; delete options.filter_policy;
@ -75,7 +79,8 @@ CLevelDBWrapper::~CLevelDBWrapper() {
options.env = NULL; options.env = NULL;
} }
bool CLevelDBWrapper::WriteBatch(CLevelDBBatch &batch, bool fSync) throw(leveldb_error) { bool CLevelDBWrapper::WriteBatch(CLevelDBBatch& batch, bool fSync) throw(leveldb_error)
{
leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
HandleError(status); HandleError(status);
return true; return true;

View File

@ -31,7 +31,9 @@ private:
leveldb::WriteBatch batch; leveldb::WriteBatch batch;
public: public:
template<typename K, typename V> void Write(const K& key, const V& value) { template <typename K, typename V>
void Write(const K& key, const V& value)
{
CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key; ssKey << key;
@ -45,7 +47,9 @@ public:
batch.Put(slKey, slValue); batch.Put(slKey, slValue);
} }
template<typename K> void Erase(const K& key) { template <typename K>
void Erase(const K& key)
{
CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key; ssKey << key;
@ -83,7 +87,9 @@ public:
CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
~CLevelDBWrapper(); ~CLevelDBWrapper();
template<typename K, typename V> bool Read(const K& key, V& value) const throw(leveldb_error) { template <typename K, typename V>
bool Read(const K& key, V& value) const throw(leveldb_error)
{
CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key; ssKey << key;
@ -106,13 +112,17 @@ public:
return true; return true;
} }
template<typename K, typename V> bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error) { template <typename K, typename V>
bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error)
{
CLevelDBBatch batch; CLevelDBBatch batch;
batch.Write(key, value); batch.Write(key, value);
return WriteBatch(batch, fSync); return WriteBatch(batch, fSync);
} }
template<typename K> bool Exists(const K& key) const throw(leveldb_error) { template <typename K>
bool Exists(const K& key) const throw(leveldb_error)
{
CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key; ssKey << key;
@ -129,7 +139,9 @@ public:
return true; return true;
} }
template<typename K> bool Erase(const K& key, bool fSync = false) throw(leveldb_error) { template <typename K>
bool Erase(const K& key, bool fSync = false) throw(leveldb_error)
{
CLevelDBBatch batch; CLevelDBBatch batch;
batch.Erase(key); batch.Erase(key);
return WriteBatch(batch, fSync); return WriteBatch(batch, fSync);
@ -138,17 +150,20 @@ public:
bool WriteBatch(CLevelDBBatch& batch, bool fSync = false) throw(leveldb_error); bool WriteBatch(CLevelDBBatch& batch, bool fSync = false) throw(leveldb_error);
// not available for LevelDB; provide for compatibility with BDB // not available for LevelDB; provide for compatibility with BDB
bool Flush() { bool Flush()
{
return true; return true;
} }
bool Sync() throw(leveldb_error) { bool Sync() throw(leveldb_error)
{
CLevelDBBatch batch; CLevelDBBatch batch;
return WriteBatch(batch, true); return WriteBatch(batch, true);
} }
// not exactly clean encapsulation, but it's easiest for now // not exactly clean encapsulation, but it's easiest for now
leveldb::Iterator *NewIterator() { leveldb::Iterator* NewIterator()
{
return pdb->NewIterator(iteroptions); return pdb->NewIterator(iteroptions);
} }
}; };

View File

@ -9,7 +9,8 @@
#include <map> #include <map>
/** STL-like map container that only keeps the N elements with the highest value. */ /** STL-like map container that only keeps the N elements with the highest value. */
template <typename K, typename V> class limitedmap template <typename K, typename V>
class limitedmap
{ {
public: public:
typedef K key_type; typedef K key_type;
@ -36,10 +37,8 @@ public:
void insert(const value_type& x) void insert(const value_type& x)
{ {
std::pair<iterator, bool> ret = map.insert(x); std::pair<iterator, bool> ret = map.insert(x);
if (ret.second) if (ret.second) {
{ if (nMaxSize && map.size() == nMaxSize) {
if (nMaxSize && map.size() == nMaxSize)
{
map.erase(rmap.begin()->second); map.erase(rmap.begin()->second);
rmap.erase(rmap.begin()); rmap.erase(rmap.begin());
} }
@ -54,8 +53,7 @@ public:
return; return;
std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second); std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second);
for (rmap_iterator it = itPair.first; it != itPair.second; ++it) for (rmap_iterator it = itPair.first; it != itPair.second; ++it)
if (it->second == itTarget) if (it->second == itTarget) {
{
rmap.erase(it); rmap.erase(it);
map.erase(itTarget); map.erase(itTarget);
return; return;
@ -72,8 +70,7 @@ public:
return; return;
std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second); std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second);
for (rmap_iterator it = itPair.first; it != itPair.second; ++it) for (rmap_iterator it = itPair.first; it != itPair.second; ++it)
if (it->second == itTarget) if (it->second == itTarget) {
{
rmap.erase(it); rmap.erase(it);
itTarget->second = v; itTarget->second = v;
rmap.insert(make_pair(v, itTarget)); rmap.insert(make_pair(v, itTarget));
@ -88,8 +85,7 @@ public:
size_type max_size(size_type s) size_type max_size(size_type s)
{ {
if (s) if (s)
while (map.size() > s) while (map.size() > s) {
{
map.erase(rmap.begin()->second); map.erase(rmap.begin()->second);
rmap.erase(rmap.begin()); rmap.erase(rmap.begin());
} }

View File

@ -10,7 +10,8 @@
#include <utility> #include <utility>
/** STL-like set container that only keeps the most recent N elements. */ /** STL-like set container that only keeps the most recent N elements. */
template <typename T> class mruset template <typename T>
class mruset
{ {
public: public:
typedef T key_type; typedef T key_type;
@ -32,17 +33,19 @@ public:
bool empty() const { return set.empty(); } bool empty() const { return set.empty(); }
iterator find(const key_type& k) const { return set.find(k); } iterator find(const key_type& k) const { return set.find(k); }
size_type count(const key_type& k) const { return set.count(k); } size_type count(const key_type& k) const { return set.count(k); }
void clear() { set.clear(); queue.clear(); } void clear()
{
set.clear();
queue.clear();
}
bool inline friend operator==(const mruset<T>& a, const mruset<T>& b) { return a.set == b.set; } bool inline friend operator==(const mruset<T>& a, const mruset<T>& b) { return a.set == b.set; }
bool inline friend operator==(const mruset<T>& a, const std::set<T>& b) { return a.set == b; } bool inline friend operator==(const mruset<T>& a, const std::set<T>& b) { return a.set == b; }
bool inline friend operator<(const mruset<T>& a, const mruset<T>& b) { return a.set < b.set; } bool inline friend operator<(const mruset<T>& a, const mruset<T>& b) { return a.set < b.set; }
std::pair<iterator, bool> insert(const key_type& x) std::pair<iterator, bool> insert(const key_type& x)
{ {
std::pair<iterator, bool> ret = set.insert(x); std::pair<iterator, bool> ret = set.insert(x);
if (ret.second) if (ret.second) {
{ if (nMaxSize && queue.size() == nMaxSize) {
if (nMaxSize && queue.size() == nMaxSize)
{
set.erase(queue.front()); set.erase(queue.front());
queue.pop_front(); queue.pop_front();
} }
@ -54,8 +57,7 @@ public:
size_type max_size(size_type s) size_type max_size(size_type s)
{ {
if (s) if (s)
while (queue.size() > s) while (queue.size() > s) {
{
set.erase(queue.front()); set.erase(queue.front());
queue.pop_front(); queue.pop_front();
} }

View File

@ -38,7 +38,8 @@ class CMessageHeader
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
{
READWRITE(FLATDATA(pchMessageStart)); READWRITE(FLATDATA(pchMessageStart));
READWRITE(FLATDATA(pchCommand)); READWRITE(FLATDATA(pchCommand));
READWRITE(nMessageSize); READWRITE(nMessageSize);
@ -63,8 +64,7 @@ class CMessageHeader
}; };
/** nServices flags */ /** nServices flags */
enum enum {
{
NODE_NETWORK = (1 << 0), NODE_NETWORK = (1 << 0),
// Bits 24-31 are reserved for temporary experiments. Just pick a bit that // Bits 24-31 are reserved for temporary experiments. Just pick a bit that
@ -88,7 +88,8 @@ class CAddress : public CService
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
{
if (ser_action.ForRead()) if (ser_action.ForRead())
Init(); Init();
if (nType & SER_DISK) if (nType & SER_DISK)
@ -122,7 +123,8 @@ class CInv
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
{
READWRITE(type); READWRITE(type);
READWRITE(hash); READWRITE(hash);
} }
@ -139,8 +141,7 @@ class CInv
uint256 hash; uint256 hash;
}; };
enum enum {
{
MSG_TX = 1, MSG_TX = 1,
MSG_BLOCK, MSG_BLOCK,
// Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however, // Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however,

View File

@ -60,8 +60,7 @@ void RandAddSeedPerfmon()
long ret = 0; long ret = 0;
unsigned long nSize = 0; unsigned long nSize = 0;
const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
while (true) while (true) {
{
nSize = vData.size(); nSize = vData.size();
ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize); ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize) if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
@ -69,15 +68,13 @@ void RandAddSeedPerfmon()
vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
} }
RegCloseKey(HKEY_PERFORMANCE_DATA); RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS) if (ret == ERROR_SUCCESS) {
{
RAND_add(begin_ptr(vData), nSize, nSize / 100.0); RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
OPENSSL_cleanse(begin_ptr(vData), nSize); OPENSSL_cleanse(begin_ptr(vData), nSize);
LogPrint("rand", "%s: %lu bytes\n", __func__, nSize); LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
} else { } else {
static bool warned = false; // Warn only once static bool warned = false; // Warn only once
if (!warned) if (!warned) {
{
LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret); LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
warned = true; warned = true;
} }
@ -126,8 +123,7 @@ uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic) void seed_insecure_rand(bool fDeterministic)
{ {
// The seed values have some unlikely fixed points which we avoid. // The seed values have some unlikely fixed points which we avoid.
if(fDeterministic) if (fDeterministic) {
{
insecure_rand_Rz = insecure_rand_Rw = 11; insecure_rand_Rz = insecure_rand_Rw = 11;
} else { } else {
uint32_t tmp; uint32_t tmp;

View File

@ -32,8 +32,7 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
// Complain if any thread tries to lock in a different order. // Complain if any thread tries to lock in a different order.
// //
struct CLockLocation struct CLockLocation {
{
CLockLocation(const char* pszName, const char* pszFile, int nLine) CLockLocation(const char* pszName, const char* pszFile, int nLine)
{ {
mutexName = pszName; mutexName = pszName;
@ -65,17 +64,19 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch,
{ {
LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
LogPrintf("Previous lock order was:\n"); LogPrintf("Previous lock order was:\n");
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2) BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) {
{ if (i.first == mismatch.first)
if (i.first == mismatch.first) LogPrintf(" (1)"); LogPrintf(" (1)");
if (i.first == mismatch.second) LogPrintf(" (2)"); if (i.first == mismatch.second)
LogPrintf(" (2)");
LogPrintf(" %s\n", i.second.ToString()); LogPrintf(" %s\n", i.second.ToString());
} }
LogPrintf("Current lock order is:\n"); LogPrintf("Current lock order is:\n");
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1) BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) {
{ if (i.first == mismatch.first)
if (i.first == mismatch.first) LogPrintf(" (1)"); LogPrintf(" (1)");
if (i.first == mismatch.second) LogPrintf(" (2)"); if (i.first == mismatch.second)
LogPrintf(" (2)");
LogPrintf(" %s\n", i.second.ToString()); LogPrintf(" %s\n", i.second.ToString());
} }
} }
@ -92,7 +93,8 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
if (!fTry) { if (!fTry) {
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) { BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) {
if (i.first == c) break; if (i.first == c)
break;
std::pair<void*, void*> p1 = std::make_pair(i.first, c); std::pair<void*, void*> p1 = std::make_pair(i.first, c);
if (lockorders.count(p1)) if (lockorders.count(p1))
@ -100,8 +102,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
lockorders[p1] = (*lockstack); lockorders[p1] = (*lockstack);
std::pair<void*, void*> p2 = std::make_pair(c, i.first); std::pair<void*, void*> p2 = std::make_pair(c, i.first);
if (lockorders.count(p2)) if (lockorders.count(p2)) {
{
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
break; break;
} }
@ -112,8 +113,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
static void pop_lock() static void pop_lock()
{ {
if (fDebug) if (fDebug) {
{
const CLockLocation& locklocation = (*lockstack).rbegin()->second; const CLockLocation& locklocation = (*lockstack).rbegin()->second;
LogPrint("lock", "Unlocked: %s\n", locklocation.ToString()); LogPrint("lock", "Unlocked: %s\n", locklocation.ToString());
} }
@ -143,9 +143,9 @@ std::string LocksHeld()
void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs)
{ {
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack) BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack)
if (i.first == cs) return; if (i.first == cs)
fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", return;
pszName, pszFile, nLine, LocksHeld().c_str()); fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str());
abort(); abort();
} }

View File

@ -48,7 +48,6 @@ LEAVE_CRITICAL_SECTION(mutex); // no RAII
*/ */
/////////////////////////////// ///////////////////////////////
// // // //
// THE ACTUAL IMPLEMENTATION // // THE ACTUAL IMPLEMENTATION //
@ -93,7 +92,9 @@ void LeaveCritical();
std::string LocksHeld(); std::string LocksHeld();
void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs); void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs);
#else #else
void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {} void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false)
{
}
void static inline LeaveCritical() {} void static inline LeaveCritical() {}
void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {} void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {}
#endif #endif
@ -114,8 +115,7 @@ private:
{ {
EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex())); EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()));
#ifdef DEBUG_LOCKCONTENTION #ifdef DEBUG_LOCKCONTENTION
if (!lock.try_lock()) if (!lock.try_lock()) {
{
PrintLockContention(pszName, pszFile, nLine); PrintLockContention(pszName, pszFile, nLine);
#endif #endif
lock.lock(); lock.lock();
@ -182,7 +182,8 @@ private:
public: public:
CSemaphore(int init) : value(init) {} CSemaphore(int init) : value(init) {}
void wait() { void wait()
{
boost::unique_lock<boost::mutex> lock(mutex); boost::unique_lock<boost::mutex> lock(mutex);
while (value < 1) { while (value < 1) {
condition.wait(lock); condition.wait(lock);
@ -190,7 +191,8 @@ public:
value--; value--;
} }
bool try_wait() { bool try_wait()
{
boost::unique_lock<boost::mutex> lock(mutex); boost::unique_lock<boost::mutex> lock(mutex);
if (value < 1) if (value < 1)
return false; return false;
@ -198,7 +200,8 @@ public:
return true; return true;
} }
void post() { void post()
{
{ {
boost::unique_lock<boost::mutex> lock(mutex); boost::unique_lock<boost::mutex> lock(mutex);
value++; value++;
@ -215,27 +218,31 @@ private:
bool fHaveGrant; bool fHaveGrant;
public: public:
void Acquire() { void Acquire()
{
if (fHaveGrant) if (fHaveGrant)
return; return;
sem->wait(); sem->wait();
fHaveGrant = true; fHaveGrant = true;
} }
void Release() { void Release()
{
if (!fHaveGrant) if (!fHaveGrant)
return; return;
sem->post(); sem->post();
fHaveGrant = false; fHaveGrant = false;
} }
bool TryAcquire() { bool TryAcquire()
{
if (!fHaveGrant && sem->try_wait()) if (!fHaveGrant && sem->try_wait())
fHaveGrant = true; fHaveGrant = true;
return fHaveGrant; return fHaveGrant;
} }
void MoveTo(CSemaphoreGrant &grant) { void MoveTo(CSemaphoreGrant& grant)
{
grant.Release(); grant.Release();
grant.sem = sem; grant.sem = sem;
grant.fHaveGrant = fHaveGrant; grant.fHaveGrant = fHaveGrant;
@ -245,18 +252,21 @@ public:
CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {} CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {}
CSemaphoreGrant(CSemaphore &sema, bool fTry = false) : sem(&sema), fHaveGrant(false) { CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false)
{
if (fTry) if (fTry)
TryAcquire(); TryAcquire();
else else
Acquire(); Acquire();
} }
~CSemaphoreGrant() { ~CSemaphoreGrant()
{
Release(); Release();
} }
operator bool() { operator bool()
{
return fHaveGrant; return fHaveGrant;
} }
}; };

View File

@ -15,15 +15,16 @@ class CNetAddr;
/** Median filter over a stream of values. /** Median filter over a stream of values.
* Returns the median of the last N numbers * Returns the median of the last N numbers
*/ */
template <typename T> class CMedianFilter template <typename T>
class CMedianFilter
{ {
private: private:
std::vector<T> vValues; std::vector<T> vValues;
std::vector<T> vSorted; std::vector<T> vSorted;
unsigned int nSize; unsigned int nSize;
public: public:
CMedianFilter(unsigned int size, T initial_value): CMedianFilter(unsigned int size, T initial_value) : nSize(size)
nSize(size)
{ {
vValues.reserve(size); vValues.reserve(size);
vValues.push_back(initial_value); vValues.push_back(initial_value);
@ -32,8 +33,7 @@ public:
void input(T value) void input(T value)
{ {
if(vValues.size() == nSize) if (vValues.size() == nSize) {
{
vValues.erase(vValues.begin()); vValues.erase(vValues.begin());
} }
vValues.push_back(value); vValues.push_back(value);
@ -50,8 +50,7 @@ public:
if (size & 1) // Odd number of elements if (size & 1) // Odd number of elements
{ {
return vSorted[size / 2]; return vSorted[size / 2];
} } else // Even number of elements
else // Even number of elements
{ {
return (vSorted[size / 2 - 1] + vSorted[size / 2]) / 2; return (vSorted[size / 2 - 1] + vSorted[size / 2]) / 2;
} }

View File

@ -113,7 +113,8 @@ base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
} }
template <unsigned int BITS> template <unsigned int BITS>
int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const { int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const
{
for (int i = WIDTH - 1; i >= 0; i--) { for (int i = WIDTH - 1; i >= 0; i--) {
if (pn[i] < b.pn[i]) if (pn[i] < b.pn[i])
return -1; return -1;
@ -124,7 +125,8 @@ int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const {
} }
template <unsigned int BITS> template <unsigned int BITS>
bool base_uint<BITS>::EqualTo(uint64_t b) const { bool base_uint<BITS>::EqualTo(uint64_t b) const
{
for (int i = WIDTH - 1; i >= 2; i--) { for (int i = WIDTH - 1; i >= 2; i--) {
if (pn[i]) if (pn[i])
return false; return false;
@ -295,24 +297,43 @@ uint32_t uint256::GetCompact(bool fNegative) const
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
{ {
// Taken from lookup3, by Bob Jenkins. // Taken from lookup3, by Bob Jenkins.
a -= c; a ^= ((c << 4) | (c >> 28)); c += b; a -= c;
b -= a; b ^= ((a << 6) | (a >> 26)); a += c; a ^= ((c << 4) | (c >> 28));
c -= b; c ^= ((b << 8) | (b >> 24)); b += a; c += b;
a -= c; a ^= ((c << 16) | (c >> 16)); c += b; b -= a;
b -= a; b ^= ((a << 19) | (a >> 13)); a += c; b ^= ((a << 6) | (a >> 26));
c -= b; c ^= ((b << 4) | (b >> 28)); b += a; a += c;
c -= b;
c ^= ((b << 8) | (b >> 24));
b += a;
a -= c;
a ^= ((c << 16) | (c >> 16));
c += b;
b -= a;
b ^= ((a << 19) | (a >> 13));
a += c;
c -= b;
c ^= ((b << 4) | (b >> 28));
b += a;
} }
static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
{ {
// Taken from lookup3, by Bob Jenkins. // Taken from lookup3, by Bob Jenkins.
c ^= b; c -= ((b << 14) | (b >> 18)); c ^= b;
a ^= c; a -= ((c << 11) | (c >> 21)); c -= ((b << 14) | (b >> 18));
b ^= a; b -= ((a << 25) | (a >> 7)); a ^= c;
c ^= b; c -= ((b << 16) | (b >> 16)); a -= ((c << 11) | (c >> 21));
a ^= c; a -= ((c << 4) | (c >> 28)); b ^= a;
b ^= a; b -= ((a << 14) | (a >> 18)); b -= ((a << 25) | (a >> 7));
c ^= b; c -= ((b << 24) | (b >> 8)); c ^= b;
c -= ((b << 16) | (b >> 16));
a ^= c;
a -= ((c << 4) | (c >> 28));
b ^= a;
b -= ((a << 14) | (a >> 18));
c ^= b;
c -= ((b << 24) | (b >> 8));
} }
uint64_t uint256::GetHash(const uint256& salt) const uint64_t uint256::GetHash(const uint256& salt) const