From f0d221e56a12947b67b9c8f43cc5832b665052c8 Mon Sep 17 00:00:00 2001 From: bc4-old-c-coder Date: Fri, 18 Apr 2014 01:02:39 -0400 Subject: [PATCH] for a working MSVC++ bitcoind.exe version 0.8.6 A full bitcoind.exe 0.8.6, with all asserts with side effects duplicated in release mode. All STL collection out of range references fixed with no change to the gcc sources. Added start up display of Boost and levelDB versions to complement the existing OpenSSL version info. BTW this links and runs with OpenSSL 1.0.1g.. The MSVC++ code has added compile time warning level control to allow better inspection of "suspect code". Added code to allow debug output to the log file to actually work when DEBUG_LOCKCONTENTION-and DEBUG_LOCKORDER are defined.. This would be useful in the gcc compiled version too. Many other startup instrumentation parts were added in the process of sorting out the problems in porting to MSVC, but they are all only in play on the MS compiler. Todo: add release mode assert mirror code to json_spirit_reader and writer_template.h files, since I missed them! Ron --- src/JustInCase.h | 14 + src/MSVC_warnings.h | 20 ++ src/MSVC_warnings.pop.h | 7 + src/MSVC_warnings.push.h | 17 ++ src/addrman.cpp | 174 +++++++++++- src/addrman.h | 183 +++++++++++- src/alert.cpp | 7 + src/allocators.h | 16 ++ src/base58.h | 22 ++ src/bignum.h | 7 + src/bitcoinrpc.cpp | 167 +++++++++-- src/bitcoinrpc.h | 3 + src/bloom.cpp | 8 + src/checkqueue.h | 28 +- src/crypter.cpp | 10 + src/db.cpp | 82 +++++- src/db.h | 34 ++- src/hash.h | 5 + src/init.cpp | 236 +++++++++++++++- src/key.cpp | 10 + src/keystore.cpp | 10 + src/leveldb.cpp | 10 + src/leveldb.h | 36 ++- src/limitedmap.h | 22 ++ src/main.cpp | 571 ++++++++++++++++++++++++++++++++++++-- src/main.h | 43 ++- src/net.cpp | 80 +++++- src/net.h | 42 +++ src/netbase.cpp | 64 ++++- src/noui.cpp | 5 + src/protocol.cpp | 6 + src/rpcblockchain.cpp | 96 +++++++ src/rpcmining.cpp | 11 + src/rpcnet.cpp | 6 + src/rpcrawtransaction.cpp | 21 ++ src/rpcwallet.cpp | 10 + src/script.cpp | 180 +++++++++++- src/script.h | 91 +++++- src/serialize.h | 66 +++++ src/sync.cpp | 12 + src/txdb.cpp | 66 ++++- src/uint256.h | 7 + src/util.cpp | 113 +++++++- src/util.h | 11 + src/wallet.cpp | 192 ++++++++++++- src/wallet.h | 4 + 46 files changed, 2721 insertions(+), 104 deletions(-) create mode 100644 src/JustInCase.h create mode 100644 src/MSVC_warnings.h create mode 100644 src/MSVC_warnings.pop.h create mode 100644 src/MSVC_warnings.push.h diff --git a/src/JustInCase.h b/src/JustInCase.h new file mode 100644 index 0000000000000..813d5fbc5a6cd --- /dev/null +++ b/src/JustInCase.h @@ -0,0 +1,14 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_JUSTINCASE_H +#define BITCOIN_JUSTINCASE_H + +#ifdef _MSC_VER + #define __PRETTY_FUNCTION__ __FUNCTION__ + #ifndef _DEBUG + extern void releaseModeAssertionfailure( const char* pFileName, const int nL, const std::string strFunctionName ); + #endif +#endif +#endif diff --git a/src/MSVC_warnings.h b/src/MSVC_warnings.h new file mode 100644 index 0000000000000..ede23c9dc0f28 --- /dev/null +++ b/src/MSVC_warnings.h @@ -0,0 +1,20 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma warning(disable:4503) // decorated name > the compiler limit (4096 characters, yikes!), truncated +#pragma warning( push ) +#pragma warning(disable:4101) // local variable is never used +#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable:4244) // floating point type to an integer type. A possible loss of data +#pragma warning(disable:4267) // size_t' to 'type', possible loss of data +#pragma warning(disable:4288) // loop control variable declared in the for-loop is used outside the for-loop scope +#pragma warning(disable:4290) // function is declared using exception specification +#pragma warning(disable:4345) // object of POD type with an initializer of the form () will be default-initialized +//#pragma warning(disable:4503) // decorated name > the compiler limit (4096), truncated +#pragma warning(disable:4717) // recurse function +#pragma warning(disable:4786) // >255 char symbols for debugging +#pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning) +#pragma warning(disable:4804) // unsafe bool usage, e.g. unary operator (-) or the complement operator (~). +#pragma warning(disable:4805) // comparison operations between unsafe bool and int for example +#pragma warning(disable:4996) // function that was marked with deprecated. \ No newline at end of file diff --git a/src/MSVC_warnings.pop.h b/src/MSVC_warnings.pop.h new file mode 100644 index 0000000000000..f5de36d94a601 --- /dev/null +++ b/src/MSVC_warnings.pop.h @@ -0,0 +1,7 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifdef THE_BLUE_PILL + #pragma warning( pop ) +#endif \ No newline at end of file diff --git a/src/MSVC_warnings.push.h b/src/MSVC_warnings.push.h new file mode 100644 index 0000000000000..d073a18c19756 --- /dev/null +++ b/src/MSVC_warnings.push.h @@ -0,0 +1,17 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifdef THE_BLUE_PILL + // You take the blue pill – the story ends, you wake up in your bed and + // believe whatever you want to believe + + #ifdef THE_RED_PILL + // You take the red pill – you stay in Wonderland, and I show you how + // deep the rabbit hole goes. Remember, all I'm offering is the truth – nothing more + // [ at Warning level 3! ] + #pragma warning( push ) + #else + #include "MSVC_warnings.h" + #endif +#endif \ No newline at end of file diff --git a/src/addrman.cpp b/src/addrman.cpp index 780edde90f7cb..f8a6a97a482d6 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -2,6 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "msvc_warnings.push.h" +#endif + #include "addrman.h" #include "hash.h" @@ -108,13 +115,43 @@ void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) if (nRndPos1 == nRndPos2) return; +#ifdef _MSC_VER + bool + fTest = ( + (nRndPos1 < vRandom.size()) && + (nRndPos2 < vRandom.size()) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size()); - +#endif int nId1 = vRandom[nRndPos1]; int nId2 = vRandom[nRndPos2]; - +#ifdef _MSC_VER + fTest = (1 == mapInfo.count(nId1)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + + fTest = (1 == mapInfo.count(nId2)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapInfo.count(nId1) == 1); assert(mapInfo.count(nId2) == 1); +#endif mapInfo[nId1].nRandomPos = nRndPos2; mapInfo[nId2].nRandomPos = nRndPos1; @@ -137,7 +174,21 @@ int CAddrMan::SelectTried(int nKBucket) int nTemp = vTried[nPos]; vTried[nPos] = vTried[i]; vTried[i] = nTemp; +#ifdef _MSC_VER + bool + fTest = ( + (-1 == nOldest) || + (1 == mapInfo.count(nTemp)) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nOldest == -1 || mapInfo.count(nTemp) == 1); +#endif if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) { nOldest = nTemp; nOldestPos = nPos; @@ -149,13 +200,37 @@ int CAddrMan::SelectTried(int nKBucket) int CAddrMan::ShrinkNew(int nUBucket) { +#ifdef _MSC_VER + bool + fTest = ( + (nUBucket >= 0) && + ((unsigned int)nUBucket < vvNew.size()) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size()); +#endif std::set &vNew = vvNew[nUBucket]; // first look for deletable items for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) { +#ifdef _MSC_VER + fTest = mapInfo.count(*it); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapInfo.count(*it)); +#endif CAddrInfo &info = mapInfo[*it]; if (info.IsTerrible()) { @@ -180,13 +255,36 @@ int CAddrMan::ShrinkNew(int nUBucket) { if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) { +#ifdef _MSC_VER + fTest = ( + (-1 == nOldest) || + (1 == mapInfo.count(*it)) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nOldest == -1 || mapInfo.count(*it) == 1); +#endif if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime) nOldest = *it; } nI++; } +#ifdef _MSC_VER + fTest = (1 == mapInfo.count(nOldest)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapInfo.count(nOldest) == 1); +#endif CAddrInfo &info = mapInfo[nOldest]; if (--info.nRefCount == 0) { @@ -203,7 +301,18 @@ int CAddrMan::ShrinkNew(int nUBucket) void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) { +#ifdef _MSC_VER + bool + fTest = (1 == vvNew[nOrigin].count(nId)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(vvNew[nOrigin].count(nId) == 1); +#endif // remove the entry from all new buckets for (std::vector >::iterator it = vvNew.begin(); it != vvNew.end(); it++) @@ -213,7 +322,17 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) } nNew--; +#ifdef _MSC_VER + fTest = (0 == info.nRefCount); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(info.nRefCount == 0); +#endif // what tried bucket to move the entry to int nKBucket = info.GetTriedBucket(nKey); @@ -232,7 +351,17 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) int nPos = SelectTried(nKBucket); // find which new bucket it belongs to +#ifdef _MSC_VER + fTest = (1 == mapInfo.count(vTried[nPos])); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapInfo.count(vTried[nPos]) == 1); +#endif int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey); std::set &vNew = vvNew[nUBucket]; @@ -392,8 +521,13 @@ CAddress CAddrMan::Select_(int nUnkBias) if (size() == 0) return CAddress(); +#ifdef _MSC_VER + double nCorTried = sqrt(double(nTried)) * (100.0 - nUnkBias); + double nCorNew = sqrt(double(nNew)) * nUnkBias; +#else double nCorTried = sqrt(nTried) * (100.0 - nUnkBias); double nCorNew = sqrt(nNew) * nUnkBias; +#endif if ((nCorTried + nCorNew)*GetRandInt(1<<30)/(1<<30) < nCorTried) { // use a tried node @@ -404,7 +538,18 @@ CAddress CAddrMan::Select_(int nUnkBias) std::vector &vTried = vvTried[nKBucket]; if (vTried.size() == 0) continue; int nPos = GetRandInt(vTried.size()); +#ifdef _MSC_VER + bool + fTest = (1 == mapInfo.count(vTried[nPos])); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapInfo.count(vTried[nPos]) == 1); +#endif CAddrInfo &info = mapInfo[vTried[nPos]]; if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) return info; @@ -422,7 +567,18 @@ CAddress CAddrMan::Select_(int nUnkBias) std::set::iterator it = vNew.begin(); while (nPos--) it++; +#ifdef _MSC_VER + bool + fTest = (1 == mapInfo.count(*it)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapInfo.count(*it) == 1); +#endif CAddrInfo &info = mapInfo[*it]; if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) return info; @@ -502,7 +658,18 @@ void CAddrMan::GetAddr_(std::vector &vAddr) { int nRndPos = GetRandInt(vRandom.size() - n) + n; SwapRandom(n, nRndPos); +#ifdef _MSC_VER + bool + fTest = (1 == mapInfo.count(vRandom[n])); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapInfo.count(vRandom[n]) == 1); +#endif vAddr.push_back(mapInfo[vRandom[n]]); } } @@ -526,3 +693,6 @@ void CAddrMan::Connected_(const CService &addr, int64 nTime) if (nTime - info.nTime > nUpdateInterval) info.nTime = nTime; } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif \ No newline at end of file diff --git a/src/addrman.h b/src/addrman.h index be6db8360e1e8..1ea0dd3948374 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -245,8 +245,9 @@ class CAddrMan public: +#ifndef _MSC_VER IMPLEMENT_SERIALIZE - ({ + (({ // serialized format: // * version byte (currently 0) // * nKey @@ -280,6 +281,7 @@ class CAddrMan { int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; READWRITE(nUBuckets); + std::map mapUnkIds; int nIds = 0; for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) { @@ -376,7 +378,184 @@ class CAddrMan } } } - };) + });) +#else + IMPLEMENT_SERIALIZE + ( + LOCK(cs); + unsigned char + nVersion = 0; + + READWRITE(nVersion); + READWRITE(nKey); + READWRITE(nNew); + READWRITE(nTried); + + CAddrMan + *am = const_cast(this); + + if (fWrite) + { + int + nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; + + READWRITE(nUBuckets); +/************ + std::map + mapUnkIds; +************/ + int + nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) + { + if (nIds == nNew) + break; // this means nNew was wrong, oh ow + mapUnkIds[(*it).first] = nIds; + + CAddrInfo + &info = (*it).second; + + if (info.nRefCount) + { + READWRITE(info); + nIds++; + } + } + nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) + { + if (nIds == nTried) + break; /* this means nTried was wrong, oh ow */ + + CAddrInfo + &info = (*it).second; + + if (info.fInTried) + { + READWRITE(info); + nIds++; + } + } + for ( + std::vector >::iterator it = am->vvNew.begin(); + it != am->vvNew.end(); + it++ + ) + { + std::set + &vNew = (*it); + + int + nSize = int( vNew.size() ); + + READWRITE(nSize); + for (std::set::iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) + { + int + nIndex = mapUnkIds[*it2]; + READWRITE(nIndex); + } + } + } + else + { + int + nUBuckets = 0; + + READWRITE(nUBuckets); + am->nIdCount = 0; + am->mapInfo.clear(); + am->mapAddr.clear(); + am->vRandom.clear(); + am->vvTried = + std::vector >( + ADDRMAN_TRIED_BUCKET_COUNT, + std::vector(0) + ); + am->vvNew = + std::vector >( + ADDRMAN_NEW_BUCKET_COUNT, + std::set() + ); + for (int n = 0; n < am->nNew; n++) + { + CAddrInfo + &info = am->mapInfo[n]; + + READWRITE(info); + am->mapAddr[info] = n; + info.nRandomPos = int( vRandom.size() ); + am->vRandom.push_back(n); + if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) + { + am->vvNew[info.GetNewBucket(am->nKey)].insert(n); + info.nRefCount++; + } + } + am->nIdCount = am->nNew; + + int + nLost = 0; + + for (int n = 0; n < am->nTried; n++) + { + CAddrInfo + info; + + READWRITE(info); + + std::vector + &vTried = am->vvTried[info.GetTriedBucket(am->nKey)]; + + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + { + info.nRandomPos = int( vRandom.size() ); + info.fInTried = true; + am->vRandom.push_back(am->nIdCount); + am->mapInfo[am->nIdCount] = info; + am->mapAddr[info] = am->nIdCount; + vTried.push_back(am->nIdCount); + am->nIdCount++; + } + else + { + nLost++; + } + } + am->nTried -= nLost; + for (int b = 0; b < nUBuckets; b++) + { + std::set + &vNew = am->vvNew[b]; + + int + nSize = 0; + + READWRITE(nSize); + for (int n = 0; n < nSize; n++) + { + int + nIndex = 0; + + READWRITE(nIndex); + + CAddrInfo + &info = am->mapInfo[nIndex]; + + if ( + (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT) && + (info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + ) + { + info.nRefCount++; + vNew.insert(nIndex); + } + } + } + } + ) + +#endif //_MSC_VER CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) { diff --git a/src/alert.cpp b/src/alert.cpp index 8eb9451a7d72f..5345d271aeefc 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -2,6 +2,10 @@ // Alert system // +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include #include #include @@ -258,3 +262,6 @@ bool CAlert::ProcessAlert(bool fThread) printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); return true; } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif diff --git a/src/allocators.h b/src/allocators.h index eb2aed6721798..27f83fafc197b 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -31,6 +31,9 @@ #include // for sysconf #endif +#ifdef _MSC_VER + #include "justincase.h" // for releaseModeAssertionfailure() +#endif /** * Thread-safe class to keep track of locked (ie, non-swappable) memory pages. * @@ -49,7 +52,20 @@ template class LockedPageManagerBase page_size(page_size) { // Determine bitmask for extracting page from address +#ifdef _MSC_VER + bool + fTest = ( + !(page_size & (page_size-1)) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(!(page_size & (page_size-1))); // size must be power of two +#endif page_mask = ~(page_size - 1); } diff --git a/src/base58.h b/src/base58.h index be8a541f67350..7f9948cfc9c17 100644 --- a/src/base58.h +++ b/src/base58.h @@ -15,6 +15,10 @@ #ifndef BITCOIN_BASE58_H #define BITCOIN_BASE58_H +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include #include @@ -23,6 +27,10 @@ #include "script.h" #include "allocators.h" +#ifdef _MSC_VER + #include "justincase.h" // for releaseModeAssertionfailure() +#endif + static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; // Encode a byte sequence as a base58-encoded string @@ -400,7 +408,18 @@ class CBitcoinSecret : public CBase58Data public: void SetSecret(const CSecret& vchSecret, bool fCompressed) { +#ifdef _MSC_VER + bool + fTest = (32 == vchSecret.size()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(vchSecret.size() == 32); +#endif SetData(fTestNet ? 239 : 128, &vchSecret[0], vchSecret.size()); if (fCompressed) vchData.push_back(1); @@ -453,4 +472,7 @@ class CBitcoinSecret : public CBase58Data } }; +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif // BITCOIN_BASE58_H diff --git a/src/bignum.h b/src/bignum.h index 0881807d703e3..2cf365f21bf80 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -5,6 +5,10 @@ #ifndef BITCOIN_BIGNUM_H #define BITCOIN_BIGNUM_H +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include #include #include @@ -587,4 +591,7 @@ inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 31452fa1e7339..fe0729353d16c 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -3,6 +3,31 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include "msvc_warnings.push.h" + + #include "init.h" + //#include "util.h" + //#include "sync.h" + //#include "ui_interface.h" + //#include "base58.h" + #include "bitcoinrpc.h" + //#include "db.h" + + #include + #include + //#include + //#include + //#include + //#include + #include + #include + //#include + #include + //#include + //#include + //#include +#else #include "init.h" #include "util.h" #include "sync.h" @@ -24,6 +49,7 @@ #include #include #include +#endif using namespace std; using namespace boost; @@ -112,11 +138,20 @@ Value ValueFromAmount(int64 amount) std::string HexBits(unsigned int nBits) { +#ifdef _MSC_VER + union { + ::int32_t nBits; + char cBits[4]; + } uBits; + uBits.nBits = htonl((::int32_t)nBits); +#else + uBits.nBits = htonl((int32_t)nBits); union { int32_t nBits; char cBits[4]; } uBits; uBits.nBits = htonl((int32_t)nBits); +#endif return HexStr(BEGIN(uBits.cBits), END(uBits.cBits)); } @@ -202,6 +237,9 @@ static const CRPCCommand vRPCCommands[] = { "help", &help, true, true }, { "stop", &stop, true, true }, { "getblockcount", &getblockcount, true, false }, +#ifdef _MSC_VER + { "getblockcountt", &getcurrentblockandtime, true, false }, +#endif { "getconnectioncount", &getconnectioncount, true, false }, { "getpeerinfo", &getpeerinfo, true, false }, { "addnode", &addnode, true, true }, @@ -759,7 +797,18 @@ void StartRPCThreads() return; } +#ifdef _MSC_VER + bool + fTest = (NULL == rpc_io_service); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(rpc_io_service == NULL); +#endif rpc_io_service = new asio::io_service(); rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); @@ -1058,33 +1107,65 @@ Object CallRPC(const string& strMethod, const Array& params) GetConfigFile().string().c_str())); // Connect to localhost - bool fUseSSL = GetBoolArg("-rpcssl"); - asio::io_service io_service; - ssl::context context(io_service, ssl::context::sslv23); + bool + fUseSSL = GetBoolArg("-rpcssl"); + + asio::io_service + io_service; + + ssl::context + context(io_service, ssl::context::sslv23); + context.set_options(ssl::context::no_sslv2); - asio::ssl::stream sslStream(io_service, context); - SSLIOStreamDevice d(sslStream, fUseSSL); - iostreams::stream< SSLIOStreamDevice > stream(d); - if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(GetDefaultRPCPort())))) + + asio::ssl::stream + sslStream(io_service, context); + + SSLIOStreamDevice + d(sslStream, fUseSSL); + + iostreams::stream< SSLIOStreamDevice > + stream(d); + + if ( + !d.connect(GetArg("-rpcconnect", "127.0.0.1"), + GetArg("-rpcport", itostr(GetDefaultRPCPort())) + ) + ) throw runtime_error("couldn't connect to server"); // HTTP basic authentication - string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); - map mapRequestHeaders; + string + strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); + + map + mapRequestHeaders; + mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; // Send request - string strRequest = JSONRPCRequest(strMethod, params, 1); - string strPost = HTTPPost(strRequest, mapRequestHeaders); + string + strRequest = JSONRPCRequest(strMethod, params, 1); + + string + strPost = HTTPPost(strRequest, mapRequestHeaders); + stream << strPost << std::flush; // Receive HTTP reply status - int nProto = 0; - int nStatus = ReadHTTPStatus(stream, nProto); + int + nProto = 0; + + int + nStatus = ReadHTTPStatus(stream, nProto); // Receive HTTP reply message headers and body - map mapHeaders; - string strReply; + map + mapHeaders; + + string + strReply; + ReadHTTPMessage(stream, mapHeaders, strReply, nProto); if (nStatus == HTTP_UNAUTHORIZED) @@ -1095,10 +1176,15 @@ Object CallRPC(const string& strMethod, const Array& params) throw runtime_error("no response from server"); // Parse reply - Value valReply; + Value + valReply; + if (!read_string(strReply, valReply)) throw runtime_error("couldn't parse reply from server"); - const Object& reply = valReply.get_obj(); + + const Object + & reply = valReply.get_obj(); + if (reply.empty()) throw runtime_error("expected reply to have result, error and id properties"); @@ -1204,18 +1290,49 @@ int CommandLineRPC(int argc, char *argv[]) // Method if (argc < 2) throw runtime_error("too few parameters"); - string strMethod = argv[1]; + string + strMethod = argv[1]; + +#ifdef _MSC_VER + int + nIndex = 2; + if ((argc > 2) && IsSwitchChar(argv[2][0])) // argument has no parameter(s) + nIndex = argc; + else + { + if ((argc > 2) && !IsSwitchChar(argv[2][0])) // argument has parameter(s) + { + int + nLastArgIndex = argc - 1; + + while( IsSwitchChar(argv[nLastArgIndex][0] )) + --nLastArgIndex; + argc = ++nLastArgIndex; + } + } + + std::vector + strParams(&argv[nIndex], &argv[argc]); +#else // Parameters default to strings - std::vector strParams(&argv[2], &argv[argc]); - Array params = RPCConvertValues(strMethod, strParams); + std::vector + strParams(&argv[2], &argv[argc]); +#endif + + Array + params = RPCConvertValues(strMethod, strParams); // Execute - Object reply = CallRPC(strMethod, params); + Object + reply = CallRPC(strMethod, params); // Parse reply - const Value& result = find_value(reply, "result"); - const Value& error = find_value(reply, "error"); + const Value + & result = find_value(reply, "result"); + + const Value + & error = find_value(reply, "error"); if (error.type() != null_type) { @@ -1293,3 +1410,7 @@ int main(int argc, char *argv[]) #endif const CRPCTable tableRPC; + +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index cf5b137988356..057897cfe4390 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -190,6 +190,9 @@ extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, b extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp +#ifdef _MSC_VER +extern json_spirit::Value getcurrentblockandtime(const json_spirit::Array& params, bool fHelp); +#endif extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); diff --git a/src/bloom.cpp b/src/bloom.cpp index 6bdffdbb38c2c..882a7cfc7a559 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,6 +1,11 @@ // Copyright (c) 2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include #include @@ -180,3 +185,6 @@ void CBloomFilter::UpdateEmptyFull() isFull = full; isEmpty = empty; } +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif diff --git a/src/checkqueue.h b/src/checkqueue.h index eba424fbaa50e..47530c260b7a2 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -163,10 +163,36 @@ template class CCheckQueueControl { public: CCheckQueueControl(CCheckQueue *pqueueIn) : pqueue(pqueueIn), fDone(false) { // passed queue is supposed to be unused, or NULL - if (pqueue != NULL) { + if (pqueue != NULL) + { +#ifdef _MSC_VER + bool + fTest = (pqueue->nTotal == pqueue->nIdle); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + fTest = (0 == pqueue->nTodo); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + fTest = (true == pqueue->fAllOk); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(pqueue->nTotal == pqueue->nIdle); assert(pqueue->nTodo == 0); assert(pqueue->fAllOk == true); +#endif } } diff --git a/src/crypter.cpp b/src/crypter.cpp index a2b62a87c8151..c4957cf2b2086 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -2,6 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "msvc_warnings.push.h" +#endif + #include #include #include @@ -119,3 +126,6 @@ bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector + #endif +#endif #include #include @@ -66,8 +76,16 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) path = pathIn; filesystem::path pathLogDir = path / "database"; filesystem::create_directory(pathLogDir); +#ifdef _MSC_VER + filesystem::path + pathErrorFile = path / "BerkeleyDB_wallet_ErrorFile.log"; // call irt what it is +#else filesystem::path pathErrorFile = path / "db.log"; +#endif + +#ifndef _MSC_VER printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str()); +#endif unsigned int nEnvFlags = 0; if (GetBoolArg("-privdb", true)) @@ -95,6 +113,23 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) S_IRUSR | S_IWUSR); if (ret != 0) return error("CDB() : error %s (%d) opening database environment", DbEnv::strerror(ret), ret); +#ifdef _MSC_VER + (void)printf( + "\n" // kind of important, so give it its own space + "CDBEnv::Open()'ed successfully) on dbenv.open() the BerkeleyDB DbEnv wallet code" + "\n" + "MainDir =%s" + "\n" + "LogDir =[MainDir]/%s" + "\n" + "ErrorFile=[MainDir]/%s" // was kind of a misnomer (maybe it was never fixed?) + "\n" + "", + path.string().c_str(), + pathLogDir.filename().string().c_str(), // a bit tricky since it's a directory! + pathErrorFile.filename().string().c_str() + ); +#endif fDbEnvInit = true; fMockDb = false; @@ -136,7 +171,19 @@ void CDBEnv::MakeMock() CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)) { LOCK(cs_db); + +#ifdef _MSC_VER + bool + fTest = (0 == mapFileUseCount.count(strFile)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapFileUseCount.count(strFile) == 0); +#endif Db db(&dbenv, 0); int result = db.verify(strFile.c_str(), NULL, NULL, 0); @@ -154,7 +201,19 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector& vResult) { LOCK(cs_db); + +#ifdef _MSC_VER + bool + fTest = (0 == mapFileUseCount.count(strFile)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(mapFileUseCount.count(strFile) == 0); +#endif u_int32_t flags = DB_SALVAGE; if (fAggressive) flags |= DB_AGGRESSIVE; @@ -465,7 +524,24 @@ void CDBEnv::Flush(bool fShutdown) dbenv.log_archive(&listp, DB_ARCH_REMOVE); Close(); if (!fMockDb) - boost::filesystem::remove_all(path / "database"); +#ifdef _MSC_VER + { + try + { + boost::filesystem::remove_all(path / "database"); + } + catch (std::exception& e) + //catch(boost::filesystem::filesystem_error &error) + { + PrintExceptionContinue(&e, + "shutdown berkeley DB log " + "directory delete failure, best to reboot? And run again." + ); + } + } +#else + boost::filesystem::remove_all(path / "database"); +#endif } } } @@ -581,4 +657,6 @@ bool CAddrDB::Read(CAddrMan& addr) return true; } - +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif \ No newline at end of file diff --git a/src/db.h b/src/db.h index ea440c496079f..69ab925896008 100644 --- a/src/db.h +++ b/src/db.h @@ -5,6 +5,10 @@ #ifndef BITCOIN_DB_H #define BITCOIN_DB_H +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include "main.h" #include @@ -147,8 +151,20 @@ class CDB if (!pdb) return false; if (fReadOnly) +#ifdef _MSC_VER + { + bool + fTest = !"Write called on database in read-only mode"; + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + } +#else assert(!"Write called on database in read-only mode"); - +#endif // Key CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); @@ -176,7 +192,20 @@ class CDB if (!pdb) return false; if (fReadOnly) +#ifdef _MSC_VER + { + bool + fTest = (!"Erase called on database in read-only mode"); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + } +#else assert(!"Erase called on database in read-only mode"); +#endif // Key CDataStream ssKey(SER_DISK, CLIENT_VERSION); @@ -324,4 +353,7 @@ class CAddrDB bool Read(CAddrMan& addr); }; +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif // BITCOIN_DB_H diff --git a/src/hash.h b/src/hash.h index 28e75ede99f37..019a8666f48a6 100644 --- a/src/hash.h +++ b/src/hash.h @@ -108,7 +108,12 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL inline uint160 Hash160(const std::vector& vch) { uint256 hash1; +#ifdef _MSC_VER + //SHA256(vch.data(), vch.size(), (unsigned char*)&hash1); + SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); +#else SHA256(vch.data(), vch.size(), (unsigned char*)&hash1); +#endif uint160 hash2; RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); return hash2; diff --git a/src/init.cpp b/src/init.cpp index 68ca62288db8d..9f836691ab1b9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -3,6 +3,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include "txdb.h" #include "walletdb.h" #include "bitcoinrpc.h" @@ -141,10 +145,52 @@ void HandleSIGHUP(int) { fReopenDebugLog = true; } +#ifdef WIN32 +static int WindowsHandleSigterm( unsigned long the_signal ) +{ +bool + fIWillHandleIt = false; + +switch( the_signal ) + { + case CTRL_C_EVENT: //A CTRL+c signal was received, + //either from keyboard input + //or from a signal generated by the + //GenerateConsoleCtrlEvent function + case CTRL_BREAK_EVENT: //A CTRL+BREAK signal was received, + //either from keyboard input + //or from a signal generated by the + //GenerateConsoleCtrlEvent function + case CTRL_CLOSE_EVENT: // A signal that the system sends to all processes + // attached to a console when the user closes + // the console (either by choosing the Close + // command from the console window's System menu, + // or by choosing the End Task command from the + // Task List). + case CTRL_LOGOFF_EVENT: //A signal that the system sends to all console + // processes when a user is logging off. This + // signal does not indicate which user is + // logging off, so no assumptions can be made. + + case CTRL_SHUTDOWN_EVENT: // I think we should do something here too? + + // so we handle all 5 of these cases! + // I tested all 5 andthey all work! Ron + + HandleSIGTERM( (int)the_signal ); + fIWillHandleIt = true; + break; + + default: // any other (strange) signal we pass on + break; // and just let it happen? + } +return fIWillHandleIt; +} +#endif ////////////////////////////////////////////////////////////////////////////// // @@ -195,7 +241,13 @@ bool AppInit(int argc, char* argv[]) if (fCommandLine) { int ret = CommandLineRPC(argc, argv); +#ifdef _MSC_VER + Shutdown(); + detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup)); + return fRet; +#else exit(ret); +#endif } #if !defined(WIN32) fDaemon = GetBoolArg("-daemon"); @@ -229,7 +281,8 @@ bool AppInit(int argc, char* argv[]) } catch (...) { PrintExceptionContinue(NULL, "AppInit()"); } - if (!fRet) { + if (!fRet) + { if (detectShutdownThread) detectShutdownThread->interrupt(); threadGroup.interrupt_all(); @@ -379,13 +432,37 @@ std::string HelpMessage() struct CImportingNow { - CImportingNow() { + CImportingNow() + { +#ifdef _MSC_VER + bool + fTest = (false == fImporting); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(fImporting == false); +#endif fImporting = true; } - ~CImportingNow() { + ~CImportingNow() + { +#ifdef _MSC_VER + bool + fTest = (true == fImporting); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(fImporting == true); +#endif fImporting = false; } }; @@ -491,6 +568,45 @@ bool AppInit2(boost::thread_group& threadGroup) sigemptyset(&sa_hup.sa_mask); sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); +#else + #ifdef WIN32 + // what do we do for windows aborts or Ctl-Cs, etc.? + if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE)&WindowsHandleSigterm, true ) ) + { + ; // success + } + //else exigency of wincon.h + // // we failed! + + // see http://msdn.microsoft.com/en-us/library/windows/desktop/ms686016%28v=vs.85%29.aspx + + // SetConsoleCtrlHandler is very much similar to signal(), i.e. + + // BOOL SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add) ; + // versus + // void (*signal(int sig, void (__cdecl *func)(int sig[, int subcode ])))(int sig); + + // but signal() is somewhat more complicated to use, and understand! Perhaps + + // if(signal(SIGINT, SIG_IGN) != SIG_IGN) + // signal(SIGINT, WindowsHandleSigterm); + // + // the above from http://c-faq.com/osdep/sigint.html + + // for linux, I see, http://linux.die.net/man/1/erlsrv + + // the Window's signal is as below + + //SIGABRT Abnormal termination + //SIGFPE Floating-point error + //SIGILL Illegal instruction + //SIGINT CTRL+C signal + //SIGSEGV Illegal storage access + //SIGTERM Termination request + // + // func can be a function or a constant SIG_DFL or SIG_IGN.for signal(). + // + #endif #endif // ********************************************************* Step 2: parameter interactions @@ -633,6 +749,62 @@ bool AppInit2(boost::thread_group& threadGroup) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); + + printf("\n"); + printf("Using Boost version %d.%d.%d\n", // miiill (most, insignificant, least) digits + BOOST_VERSION / 100000, + (BOOST_VERSION / 100) % 1000, + BOOST_VERSION % 100 + ); +#ifdef _MSC_VER + printf("Using Boost MSVC version %d\n", BOOST_MSVC ); + printf("Using Boost MSVC full version %d.%d build %d\n", // VVM MPP PPP + BOOST_MSVC_FULL_VER / 10000000, + ( BOOST_MSVC_FULL_VER / 100000 ) % 100, + BOOST_MSVC_FULL_VER % 100000 + ); +#endif +#ifdef BOOST_GCC + //Has the value: __GNUC__ * 10000 + + // __GNUC_MINOR__ * 100 + + // __GNUC_PATCHLEVEL__ + printf("Using Boost GCC full version %d.d patch level %d\n", //AAIIpp + // __GNUC__, + BOOST_GCC / 10000, + + // __GNUC_MINOR__, + ( BOOST_GCC / 100 ) % 100, + + //__GNUC_PATCHLEVEL__ + BOOST_GCC % 100 + ); +#endif + #ifdef BOOST_WINDOWS + printf("\nWindows platform is available to Boost\n" ); + #endif +#ifdef _MSC_VER + #ifdef _DEBUG + printf("Boost is using the %s compiler\n", BOOST_COMPILER ); + printf("Boost is using the %s standard library\n", BOOST_STDLIB ); + printf("Boost is using the %s platform\n", BOOST_PLATFORM ); + #endif +#else + printf("Boost is using the %s compiler\n", BOOST_COMPILER ); + printf("Boost is using the %s standard library\n", BOOST_STDLIB ); + printf("Boost is using the %s platform\n", BOOST_PLATFORM ); +#endif + + printf( + "\n" + "Using levelDB version %d.%d" + "\n" + "", + leveldb::kMajorVersion, + leveldb::kMinorVersion + ); + + printf("\n"); + printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); if (!fLogTimestamps) printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str()); @@ -1026,9 +1198,64 @@ bool AppInit2(boost::thread_group& threadGroup) if (pindexBest && pindexBest != pindexRescan) { uiInterface.InitMessage(_("Rescanning...")); +#ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( "\n" ); + + string + strAccountToMatch = ""; + + // Find all addresses + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress + & addressFound = item.first; + + const string + & strNameFound = item.second; + + if (strNameFound == strAccountToMatch) + { + if( fPrintToConsole ) + { + (void)printf( + "%s for \"\"" + "\n" + "", + addressFound.ToString().c_str() + ); + } + } + else // another account + { + if( fPrintToConsole ) + { + (void)printf( + "%s for \"%s\"" + "\n" + "", + addressFound.ToString().c_str(), + strNameFound.c_str() + ); + } + } + } + if( fPrintToConsole ) + (void)printf( "\n" ); +#endif printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight); nStart = GetTimeMillis(); +#ifdef _MSC_VER + void( pwalletMain->ScanForWalletTransactions(pindexRescan, true, pindexBest->nHeight - pindexRescan->nHeight) ); + // we are intentionally ignoring the result of this function + // which is telling us whether or not we have had any updates to our wallet + // Is this the intent?? + + // And should it only rescan backto (or is it starting from) the "birthday" of the wallet, + // if that is known?? +#else pwalletMain->ScanForWalletTransactions(pindexRescan, true); +#endif printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); pwalletMain->SetBestChain(CBlockLocator(pindexBest)); nWalletDBUpdated++; @@ -1101,3 +1328,6 @@ bool AppInit2(boost::thread_group& threadGroup) return !fRequestShutdown; } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif diff --git a/src/key.cpp b/src/key.cpp index 75114c6afe149..ccec972a74de6 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -2,6 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "msvc_warnings.push.h" +#endif + #include #include @@ -408,3 +415,6 @@ bool CKey::IsValid() key2.SetSecret(secret, fCompr); return GetPubKey() == key2.GetPubKey(); } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif diff --git a/src/keystore.cpp b/src/keystore.cpp index e0cf805a19ea3..8e2bab5369d21 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -3,6 +3,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "msvc_warnings.push.h" +#endif + #include "keystore.h" #include "script.h" @@ -219,3 +226,6 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) } return true; } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif diff --git a/src/leveldb.cpp b/src/leveldb.cpp index e66f8514a7560..980cfb5c1334a 100644 --- a/src/leveldb.cpp +++ b/src/leveldb.cpp @@ -2,6 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "msvc_warnings.push.h" +#endif + #include "leveldb.h" #include "util.h" @@ -79,3 +86,6 @@ bool CLevelDB::WriteBatch(CLevelDBBatch &batch, bool fSync) throw(leveldb_error) } return true; } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif diff --git a/src/leveldb.h b/src/leveldb.h index 79262edbb5295..9ce7ef6f1b1d9 100644 --- a/src/leveldb.h +++ b/src/leveldb.h @@ -4,6 +4,10 @@ #ifndef BITCOIN_LEVELDB_H #define BITCOIN_LEVELDB_H +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include "serialize.h" #include @@ -91,13 +95,37 @@ class CLevelDB if (!status.ok()) { if (status.IsNotFound()) return false; +#ifdef _MSC_VER + printf( + "\n" + "LevelDB read (part1) failure: " + "%s" + "\n" + "", + status.ToString().c_str() + ); +#else printf("LevelDB read failure: %s\n", status.ToString().c_str()); +#endif HandleError(status); } - try { + try + { CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); ssValue >> value; - } catch(std::exception &e) { + } catch(std::exception &e) + { +#ifdef _MSC_VER + printf( + "\n" + "LevelDB Read (part2)failure(?): " + "%s (%s)" + "\n" + "", + status.ToString().c_str(), + e.what() + ); +#endif return false; } return true; @@ -149,5 +177,7 @@ class CLevelDB return pdb->NewIterator(iteroptions); } }; - +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif // BITCOIN_LEVELDB_H diff --git a/src/limitedmap.h b/src/limitedmap.h index 7049d68e5aaa1..11619f9c6c21d 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -60,7 +60,18 @@ template class limitedmap return; } // Shouldn't ever get here +#ifdef _MSC_VER + bool + fTest = false; //TODO remove me + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(0); //TODO remove me +#endif map.erase(itTarget); } void update(const_iterator itIn, const mapped_type& v) @@ -79,7 +90,18 @@ template class limitedmap return; } // Shouldn't ever get here +#ifdef _MSC_VER + bool + fTest = false; //TODO remove me + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(0); //TODO remove me +#endif itTarget->second = v; rmap.insert(make_pair(v, itTarget)); } diff --git a/src/main.cpp b/src/main.cpp index a90b60e02045a..b93824b470d1f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,18 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include "msvc_warnings.push.h" + + #include "alert.h" + #include "checkpoints.h" + #include "db.h" + #include "txdb.h" + #include "net.h" + #include "init.h" + #include "ui_interface.h" + #include "checkqueue.h" +#else #include "alert.h" #include "checkpoints.h" #include "db.h" @@ -11,6 +23,8 @@ #include "init.h" #include "ui_interface.h" #include "checkqueue.h" +#endif + #include #include #include @@ -214,7 +228,18 @@ std::map::iterator CCoinsViewCache::FetchCoins(const uint256 &tx CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) { std::map::iterator it = FetchCoins(txid); +#ifdef _MSC_VER + bool + fTest = (it != cacheCoins.end()); + #ifdef _DEBUG + assert(fTest); // can it be false, ever, at runtime, in release mode?? + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(it != cacheCoins.end()); +#endif return it->second; } @@ -988,11 +1013,11 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock fseek(file, postx.nTxOffset, SEEK_CUR); file >> txOut; } catch (std::exception &e) { - return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION); + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); } hashBlock = header.GetHash(); if (txOut.GetHash() != hash) - return error("%s() : txid mismatch", BOOST_CURRENT_FUNCTION); + return error("%s() : txid mismatch", __PRETTY_FUNCTION__); return true; } } @@ -1145,7 +1170,18 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl const CBlockIndex* pindexFirst = pindexLast; for (int i = 0; pindexFirst && i < nInterval-1; i++) pindexFirst = pindexFirst->pprev; +#ifdef _MSC_VER + bool + fTest = (NULL != pindexFirst); + #ifdef _DEBUG + assert(fTest); // can it be false, ever, at runtime, in release mode?? + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__); + #endif +#else assert(pindexFirst); +#endif // Limit adjustment step int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime(); @@ -1263,7 +1299,6 @@ bool ConnectBestBlock(CValidationState &state) { CBlockIndex *pindexFailed = pindexNewBest; while (pindexTest != pindexFailed) { pindexFailed->nStatus |= BLOCK_FAILED_CHILD; - setBlockIndexValid.erase(pindexFailed); pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexFailed)); pindexFailed = pindexFailed->pprev; } @@ -1314,7 +1349,18 @@ void CBlockHeader::UpdateTime(const CBlockIndex* pindexPrev) const CTxOut &CTransaction::GetOutputFor(const CTxIn& input, CCoinsViewCache& view) { const CCoins &coins = view.GetCoins(input.prevout.hash); +#ifdef _MSC_VER + bool + fTest = coins.IsAvailable(input.prevout.n); + #ifdef _DEBUG + assert(fTest); // can it be false, ever, at runtime, in release mode?? + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(coins.IsAvailable(input.prevout.n)); +#endif return coins.vout[input.prevout.n]; } @@ -1352,13 +1398,35 @@ void CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, BOOST_FOREACH(const CTxIn &txin, vin) { CCoins &coins = inputs.GetCoins(txin.prevout.hash); CTxInUndo undo; +#ifdef _MSC_VER + bool + fTest = coins.Spend(txin.prevout, undo); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(coins.Spend(txin.prevout, undo)); +#endif txundo.vprevout.push_back(undo); } } - // add outputs + // add outputs sure looks like an assert with side effects here!? +#ifdef _MSC_VER + bool + fTest = inputs.SetCoins(txhash, CCoins(*this, nHeight)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(inputs.SetCoins(txhash, CCoins(*this, nHeight))); +#endif } bool CTransaction::HaveInputs(CCoinsViewCache &inputs) const @@ -1479,7 +1547,18 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs, bool CBlock::DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, bool *pfClean) { +#ifdef _MSC_VER + bool + fTest = (pindex == view.GetBestBlock()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(pindex == view.GetBestBlock()); +#endif if (pfClean) *pfClean = false; @@ -1497,12 +1576,14 @@ bool CBlock::DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoin return error("DisconnectBlock() : block and undo data inconsistent"); // undo transactions in reverse order - for (int i = vtx.size() - 1; i >= 0; i--) { + for (int i = vtx.size() - 1; i >= 0; i--) + { const CTransaction &tx = vtx[i]; uint256 hash = tx.GetHash(); // check that all outputs are available - if (!view.HaveCoins(hash)) { + if (!view.HaveCoins(hash)) + { fClean = fClean && error("DisconnectBlock() : outputs still spent? database corrupted"); view.SetCoins(hash, CCoins()); } @@ -1521,16 +1602,30 @@ bool CBlock::DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoin outs = CCoins(); // restore inputs - if (i > 0) { // not coinbases + if (i > 0) + { // not coinbases const CTxUndo &txundo = blockUndo.vtxundo[i-1]; if (txundo.vprevout.size() != tx.vin.size()) return error("DisconnectBlock() : transaction and undo data inconsistent"); - for (unsigned int j = tx.vin.size(); j-- > 0;) { + for (unsigned int j = tx.vin.size(); j-- > 0;) + { +#ifdef _MSC_VER + if( fPrintToConsole ) + { + (void)printf( + "" + ", j=%4d" + "" + , j + ); + } +#endif const COutPoint &out = tx.vin[j].prevout; const CTxInUndo &undo = txundo.vprevout[j]; CCoins coins; view.GetCoins(out.hash, coins); // this can fail if the prevout was already entirely spent - if (undo.nHeight != 0) { + if (undo.nHeight != 0) + { // undo data contains height: this is the last output of the prevout tx being spent if (!coins.IsPruned()) fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction"); @@ -1538,7 +1633,8 @@ bool CBlock::DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoin coins.fCoinBase = undo.fCoinBase; coins.nHeight = undo.nHeight; coins.nVersion = undo.nVersion; - } else { + } else + { if (coins.IsPruned()) fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction"); } @@ -1549,17 +1645,37 @@ bool CBlock::DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoin coins.vout[out.n] = undo.txout; if (!view.SetCoins(out.hash, coins)) return error("DisconnectBlock() : cannot restore coin inputs"); +#ifdef _MSC_VER + if( fPrintToConsole ) + { + (void)printf( + "\b\b\b\b" + "\b\b\b\b" + ); + } +#endif } } +#ifdef _MSC_VER + if( fPrintToConsole ) + { + (void)printf( + "\b\b" + "\b\b\b\b" + ); + } +#endif } // move best block pointer to prevout block view.SetBestBlock(pindex->pprev); - if (pfClean) { + if (pfClean) + { *pfClean = fClean; return true; - } else { + } else + { return fClean; } } @@ -1603,7 +1719,18 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi return false; // verify that the view's current state corresponds to the previous block +#ifdef _MSC_VER + bool + fTest = (pindex->pprev == view.GetBestBlock()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(pindex->pprev == view.GetBestBlock()); +#endif // Special case for the genesis block, skipping connection of its transactions // (its coinbase is unspendable) @@ -1738,8 +1865,18 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi if (!pblocktree->WriteTxIndex(vPos)) return state.Abort(_("Failed to write transaction index")); - // add this block to the view's block chain + // add this block to the view's block chain, sure looks like an assert with side effects to me!? +#ifdef _MSC_VER + fTest = view.SetBestBlock(pindex); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(view.SetBestBlock(pindex)); +#endif // Watch for transactions paying to me for (unsigned int i=0; inHeight > pfork->nHeight) { + while (plonger->nHeight > pfork->nHeight) + { plonger = plonger->pprev; + #ifdef _MSC_VER + bool + fTest = (NULL != plonger); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(plonger != NULL); +#endif } if (pfork == plonger) break; pfork = pfork->pprev; +#ifdef _MSC_VER + bool + fTest = (NULL != pfork); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(pfork != NULL); +#endif } // List of what to disconnect (typically nothing) @@ -1830,7 +1990,18 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew) // Flush changes to global coin state int64 nStart = GetTimeMicros(); int nModified = view.GetCacheSize(); +#ifdef _MSC_VER + bool + fTest = view.Flush(); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(view.Flush()); +#endif int64 nTime = GetTimeMicros() - nStart; if (fBenchmark) printf("- Flush %i transactions: %.2fms (%.4fms/tx)\n", nModified, 0.001 * nTime, 0.001 * nTime / nModified); @@ -1873,8 +2044,9 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew) } // Delete redundant memory transactions that are in the connected branch - BOOST_FOREACH(CTransaction& tx, vDelete) { - mempool.remove(tx); + BOOST_FOREACH(CTransaction& tx, vDelete) + { + mempool.remove(tx); // Do we relly want not recursive here? mempool.removeConflicts(tx); } @@ -1937,7 +2109,18 @@ bool CBlock::AddToBlockIndex(CValidationState &state, const CDiskBlockPos &pos) // Construct new block index object CBlockIndex* pindexNew = new CBlockIndex(*this); +#ifdef _MSC_VER + bool + fTest = (NULL != pindexNew); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(pindexNew); +#endif map::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); map::iterator miPrev = mapBlockIndex.find(hashPrevBlock); @@ -2150,10 +2333,22 @@ bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerk return true; } +#ifdef _MSC_VER +bool CBlock::AcceptBlock(CValidationState &state, uint256 hash, CDiskBlockPos *dbp) +#else bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp) +#endif { +#ifdef _MSC_VER + #ifdef _DEBUG + // let's test this + assert( hash == GetHash() ); // seems always true? + #endif +#else // Check for duplicate - uint256 hash = GetHash(); + uint256 + hash = GetHash(); +#endif if (mapBlockIndex.count(hash)) return state.Invalid(error("AcceptBlock() : block already in mapBlockIndex")); @@ -2301,7 +2496,11 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl } // Store to disk - if (!pblock->AcceptBlock(state, dbp)) +#ifdef _MSC_VER + if (!pblock->AcceptBlock(state, hash, dbp)) // process => accept +#else + if (!pblock->AcceptBlock(state, dbp)) // process => accept +#endif return error("ProcessBlock() : AcceptBlock FAILED"); // Recursively process any orphan blocks that depended on this one @@ -2317,7 +2516,14 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl CBlock* pblockOrphan = (*mi).second; // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned) CValidationState stateDummy; +#ifdef _MSC_VER + uint256 + hashOrphan = pblockOrphan->GetHash(); + + if (pblockOrphan->AcceptBlock(stateDummy, hashOrphan)) +#else if (pblockOrphan->AcceptBlock(stateDummy)) +#endif vWorkQueue.push_back(pblockOrphan->GetHash()); mapOrphanBlocks.erase(pblockOrphan->GetHash()); delete pblockOrphan; @@ -2570,6 +2776,12 @@ bool static LoadBlockIndexDB() boost::this_thread::interruption_point(); +#ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( + "sorting by block height..." + ); +#endif // Calculate nChainWork vector > vSortedByHeight; vSortedByHeight.reserve(mapBlockIndex.size()); @@ -2578,7 +2790,26 @@ bool static LoadBlockIndexDB() CBlockIndex* pindex = item.second; vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); } +#ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( + "loaded..." + ); +#endif sort(vSortedByHeight.begin(), vSortedByHeight.end()); +#ifdef _MSC_VER + int + nCount = 0; + + if( fPrintToConsole ) + (void)printf( + "done" + "\n" + "building setBlockIndexValid ..." + "\n" + ); +#endif + BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; @@ -2586,7 +2817,35 @@ bool static LoadBlockIndexDB() pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS && !(pindex->nStatus & BLOCK_FAILED_MASK)) setBlockIndexValid.insert(pindex); +#ifdef _MSC_VER + const int + nEveryTenThousandth = 10000; + ++nCount; + if( + fPrintToConsole + && + (nCount && + (0 == (nCount % nEveryTenThousandth)) + ) + ) + { + if( fPrintToConsole ) + (void)printf( + "%7d" + "\r" + "" + , nCount + ); + } +#endif + } +#ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( + "done \n" + ); +#endif // Load block file info pblocktree->ReadLastBlockFile(nLastBlockFile); @@ -2630,36 +2889,82 @@ bool static LoadBlockIndexDB() return true; } -bool VerifyDB() { +bool VerifyDB() +{ if (pindexBest == NULL || pindexBest->pprev == NULL) return true; - +#ifdef _MSC_VER + const int + nBlocksPerHour = 6, + nHoursPerDay = 24, + nDaysToCheck = 2; // the only variable here +#endif // Verify blocks in the best chain int nCheckLevel = GetArg("-checklevel", 3); - int nCheckDepth = GetArg( "-checkblocks", 288); + int nCheckDepth = GetArg( "-checkblocks", +#ifdef _MSC_VER + nBlocksPerHour*nHoursPerDay*nDaysToCheck +#else + 288 +#endif + ); if (nCheckDepth == 0) nCheckDepth = 1000000000; // suffices until the year 19000 if (nCheckDepth > nBestHeight) nCheckDepth = nBestHeight; +#ifdef _MSC_VER + #ifdef _DEBUG + nCheckDepth = 100; // for speed + #endif +#endif nCheckLevel = std::max(0, std::min(4, nCheckLevel)); printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); CCoinsViewCache coins(*pcoinsTip, true); CBlockIndex* pindexState = pindexBest; CBlockIndex* pindexFailure = NULL; int nGoodTransactions = 0; +#ifdef _MSC_VER + int + nCount = 0; + + if( fPrintToConsole ) + (void)printf( + "Verifying %d " + "", + (nCheckDepth - nCount) + ); +#endif CValidationState state; for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) { boost::this_thread::interruption_point(); +#if !defined(QT_GUI) + #ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( "0" ); + #endif +#endif if (pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; // check level 0: read from disk if (!block.ReadFromDisk(pindex)) return error("VerifyDB() : *** block.ReadFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); +#if !defined(QT_GUI) + #ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( ", 1" ); + #endif +#endif // check level 1: verify block validity if (nCheckLevel >= 1 && !block.CheckBlock(state)) return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); +#if !defined(QT_GUI) + #ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( ", 2" ); + #endif +#endif // check level 2: verify undo validity if (nCheckLevel >= 2 && pindex) { CBlockUndo undo; @@ -2669,8 +2974,15 @@ bool VerifyDB() { return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); } } +#if !defined(QT_GUI) + #ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( ", 3 " ); + #endif +#endif // check level 3: check for inconsistencies during memory-only disconnect of tip blocks - if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= 2*nCoinCacheSize + 32000) { + if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= 2*nCoinCacheSize + 32000) + { bool fClean = true; if (!block.DisconnectBlock(state, pindex, coins, &fClean)) return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); @@ -2681,14 +2993,60 @@ bool VerifyDB() { } else nGoodTransactions += block.vtx.size(); } - } +#ifdef _MSC_VER + ++nCount; + #if defined(QT_GUI) + // splash should indicate life somehow, perhaps something like + switch( nCount % 4 ) + { + case 0: + uiInterface.InitMessage(_("Verifying blocks |")); + break; + case 1: + uiInterface.InitMessage(_("Verifying blocks /")); + break; + case 2: + //uiInterface.InitMessage(_("Verifying -")); + uiInterface.InitMessage(_("Verifying blocks \u2014")); + break; + case 3: + uiInterface.InitMessage(_("Verifying blocks \\")); + break; + } + #else + if( fPrintToConsole ) + { + (void)printf( + "\r" + " " + "\r" + "Verifying %d " + "", + (nCheckDepth - nCount) /* / 10 */ + ); + } + #endif +#endif + } +#if !defined(QT_GUI) + #ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( + "\r" + " " + "\r" + ); + #endif +#endif if (pindexFailure) return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", pindexBest->nHeight - pindexFailure->nHeight + 1, nGoodTransactions); // check level 4: try reconnecting blocks - if (nCheckLevel >= 4) { + if (nCheckLevel >= 4) + { CBlockIndex *pindex = pindexState; - while (pindex != pindexBest) { + while (pindex != pindexBest) + { boost::this_thread::interruption_point(); pindex = pindex->pnext; CBlock block; @@ -2696,6 +3054,27 @@ bool VerifyDB() { return error("VerifyDB() : *** block.ReadFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); if (!block.ConnectBlock(state, pindex, coins)) return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); +#if defined(QT_GUI) + #ifdef _MSC_VER + // splash should indicate life somehow, perhaps something like + switch( nCount % 4 ) + { + case 0: + uiInterface.InitMessage(_("Verifying blocks |")); + break; + case 1: + uiInterface.InitMessage(_("Verifying blocks /")); + break; + case 2: + //uiInterface.InitMessage(_("Verifying -")); + uiInterface.InitMessage(_("Verifying blocks \u2014")); + break; + case 3: + uiInterface.InitMessage(_("Verifying blocks \\")); + break; + } + #endif +#endif } } @@ -2784,9 +3163,31 @@ bool InitBlockIndex() { printf("%s\n", hash.ToString().c_str()); printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", block.hashMerkleRoot.ToString().c_str()); +#ifdef _MSC_VER + bool + fTest = ( + uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b") == + block.hashMerkleRoot + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + block.print(); + fTest = (hashGenesisBlock == hash); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); block.print(); assert(hash == hashGenesisBlock); +#endif // Start new block file try { @@ -2939,7 +3340,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) break; } } catch (std::exception &e) { - printf("%s() : Deserialize or I/O error caught during load\n", BOOST_CURRENT_FUNCTION); + printf("%s() : Deserialize or I/O error caught during load\n", __PRETTY_FUNCTION__); } } fclose(fileIn); @@ -3012,7 +3413,21 @@ string GetWarnings(string strFor) return strStatusBar; else if (strFor == "rpc") return strRPC; +#ifdef _MSC_VER + bool + fTest = (!"GetWarnings() : invalid parameter"); + (void)printf( "GetWarnings() : invalid parameter" + "\n" + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(!"GetWarnings() : invalid parameter"); +#endif return "error"; } @@ -4094,6 +4509,17 @@ void SHA256Transform(void* pstate, void* pinput, const void* pinit) SHA256_Init(&ctx); +#ifdef _MSC_VER + for (int i = 0; i < 16; i++) + ((::uint32_t*)data)[i] = ByteReverse(((::uint32_t*)pinput)[i]); + + for (int i = 0; i < 8; i++) + ctx.h[i] = ((::uint32_t*)pinit)[i]; + + SHA256_Update(&ctx, data, sizeof(data)); + for (int i = 0; i < 8; i++) + ((::uint32_t*)pstate)[i] = ctx.h[i]; +#else for (int i = 0; i < 16; i++) ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); @@ -4103,6 +4529,7 @@ void SHA256Transform(void* pstate, void* pinput, const void* pinit) SHA256_Update(&ctx, data, sizeof(data)); for (int i = 0; i < 8; i++) ((uint32_t*)pstate)[i] = ctx.h[i]; +#endif } // @@ -4270,7 +4697,21 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) if (!mempool.mapTx.count(txin.prevout.hash)) { printf("ERROR: mempool transaction missing input\n"); - if (fDebug) assert("mempool transaction missing input" == 0); + if (fDebug) +#ifdef _MSC_VER + { + bool + fTest = ("mempool transaction missing input" == 0); + #ifdef _DEBUG + assert( fTest ); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + } +#else + assert("mempool transaction missing input" == 0); +#endif fMissingInputs = true; if (porphan) vOrphan.pop_back(); @@ -4451,7 +4892,18 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& ++nExtraNonce; unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2 pblock->vtx[0].vin[0].scriptSig = (CScript() << nHeight << CBigNum(nExtraNonce)) + COINBASE_FLAGS; +#ifdef _MSC_VER + bool + fTest = (pblock->vtx[0].vin[0].scriptSig.size() <= 100); // 100 what? + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); +#endif pblock->hashMerkleRoot = pblock->BuildMerkleTree(); } @@ -4610,7 +5062,33 @@ void static BitcoinMiner(CWallet *pwallet) { // Found a solution pblock->nNonce = ByteReverse(nNonceFound); +#ifdef _MSC_VER + bool + fTest = (hash == pblock->GetHash()); + + if( !fTest ) + { + (void)printf( + "hashes don't match?" + "\n" + "%s vs." + "\n" + "%s" + "\n" + "" + , hash.ToString().c_str() + , ( pblock->GetHash() ).ToString().c_str() + ); + } + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(hash == pblock->GetHash()); +#endif SetThreadPriority(THREAD_PRIORITY_NORMAL); CheckWork(pblock, *pwalletMain, reservekey); @@ -4720,7 +5198,21 @@ uint64 CTxOutCompressor::CompressAmount(uint64 n) } if (e < 9) { int d = (n % 10); +#ifdef _MSC_VER + bool + fTest = ( + (d >= 1) && + (d <= 9) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(d >= 1 && d <= 9); +#endif n /= 10; return 1 + (n*9 + d - 1)*10 + e; } else { @@ -4760,6 +5252,9 @@ class CMainCleanup public: CMainCleanup() {} ~CMainCleanup() { +#ifdef _MSC_VER + (void)printf( "~CMainCleanup() destructor..." ); +#endif // block headers std::map::iterator it1 = mapBlockIndex.begin(); for (; it1 != mapBlockIndex.end(); it1++) @@ -4774,5 +5269,27 @@ class CMainCleanup // orphan transactions mapOrphanTransactions.clear(); +#ifdef _MSC_VER + (void)printf( "done\n" ); +#endif } } instance_of_cmaincleanup; +#ifdef _MSC_VER +void releaseModeAssertionfailure( const char* pFileName, const int nL, const std::string strFunctionName ) +{ + (void)printf( + "\n" + "file:%s, line#%d, function %s()" + "\n" + "release mode assertion failure!?" + "\n" + "\n" + "" + , pFileName //__FILE__ + , nL //__LINE__ + , strFunctionName.c_str() // __PRETTY_FUNCTION__ + ); + StartShutdown(); // maybe there are other ways?? +} + #include "msvc_warnings.pop.h" +#endif diff --git a/src/main.h b/src/main.h index e2f9bee4d290a..0e5ded3f06b55 100644 --- a/src/main.h +++ b/src/main.h @@ -5,11 +5,21 @@ #ifndef BITCOIN_MAIN_H #define BITCOIN_MAIN_H +#ifdef _MSC_VER + #include "msvc_warnings.push.h" + + #define __PRETTY_FUNCTION__ __FUNCTION__ +#endif + #include "bignum.h" #include "sync.h" #include "net.h" #include "script.h" +#ifdef _MSC_VER + #include "justincase.h" // for releaseModeAssertionfailure() +#endif + #include class CWallet; @@ -691,6 +701,7 @@ class CTxOutCompressor CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } +#ifdef _MSC_VER IMPLEMENT_SERIALIZE({ if (!fRead) { uint64 nVal = CompressAmount(txout.nValue); @@ -703,6 +714,20 @@ class CTxOutCompressor CScriptCompressor cscript(REF(txout.scriptPubKey)); READWRITE(cscript); };) +#else + IMPLEMENT_SERIALIZE(({ + if (!fRead) { + uint64 nVal = CompressAmount(txout.nValue); + READWRITE(VARINT(nVal)); + } else { + uint64 nVal = 0; + READWRITE(VARINT(nVal)); + txout.nValue = DecompressAmount(nVal); + } + CScriptCompressor cscript(REF(txout.scriptPubKey)); + READWRITE(cscript); + });) +#endif }; /** Undo information for a CTxIn @@ -816,7 +841,7 @@ class CBlockUndo filein >> hashChecksum; } catch (std::exception &e) { - return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION); + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); } // Verify checksum @@ -1460,7 +1485,7 @@ class CBlock : public CBlockHeader filein >> *this; } catch (std::exception &e) { - return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION); + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); } // Check the header @@ -1513,7 +1538,11 @@ class CBlock : public CBlockHeader // Store block on disk // if dbp is provided, the file is known to already reside on disk +#ifdef _MSC_VER + bool AcceptBlock(CValidationState &state, uint256 hash, CDiskBlockPos *dbp = NULL); +#else bool AcceptBlock(CValidationState &state, CDiskBlockPos *dbp = NULL); +#endif }; @@ -1800,7 +1829,12 @@ class CBlockIndex struct CBlockIndexWorkComparator { - bool operator()(CBlockIndex *pa, CBlockIndex *pb) { +#ifdef _MSC_VER + bool operator()(CBlockIndex *pa, CBlockIndex *pb) const +#else + bool operator()(CBlockIndex *pa, CBlockIndex *pb) +#endif + { if (pa->nChainWork > pb->nChainWork) return false; if (pa->nChainWork < pb->nChainWork) return true; @@ -2259,4 +2293,7 @@ class CMerkleBlock ) }; +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif diff --git a/src/net.cpp b/src/net.cpp index 156ab6349c3ac..90c94a856ff73 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3,6 +3,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include "db.h" #include "net.h" #include "init.h" @@ -707,9 +711,21 @@ void SocketSendData(CNode *pnode) { std::deque::iterator it = pnode->vSendMsg.begin(); - while (it != pnode->vSendMsg.end()) { + while (it != pnode->vSendMsg.end()) + { const CSerializeData &data = *it; +#ifdef _MSC_VER + bool + fTest = (data.size() > pnode->nSendOffset); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(data.size() > pnode->nSendOffset); +#endif int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT); if (nBytes > 0) { pnode->nLastSend = GetTime(); @@ -738,9 +754,29 @@ void SocketSendData(CNode *pnode) } } - if (it == pnode->vSendMsg.end()) { + if (it == pnode->vSendMsg.end()) + { +#ifdef _MSC_VER + bool + fTest = (0 == pnode->nSendOffset); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + + fTest = (0 == pnode->nSendSize); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(pnode->nSendOffset == 0); assert(pnode->nSendSize == 0); +#endif } pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it); } @@ -1518,14 +1554,43 @@ void ThreadOpenAddedConnections() { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) - for (list >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) + for (list >::iterator it = lservAddressesToAdd.begin(); + it != lservAddressesToAdd.end(); + it++ + ) + { BOOST_FOREACH(CService& addrNode, *(it)) + { +#ifndef _MSC_VER if (pnode->addr == addrNode) { it = lservAddressesToAdd.erase(it); it--; break; } + } +#else + if (pnode->addr == addrNode) + { + it = lservAddressesToAdd.erase(it); + + // now it gets tricky! + if( lservAddressesToAdd.empty() ) + break; // can't --it, nor ++it + // else it's not empty, so + if (it == lservAddressesToAdd.begin()) + break; // can't --it + --it; // finally, a legal place!! + break; + } + // else we stay in the inner BOOST_FOREACH() loop + } + if( lservAddressesToAdd.empty() ) + break; // can't do a ++it + if (it == lservAddressesToAdd.end()) + break; // can't do a ++it +#endif + } } BOOST_FOREACH(vector& vserv, lservAddressesToAdd) { @@ -1902,6 +1967,9 @@ class CNetCleanup } ~CNetCleanup() { +#ifdef _MSC_VER + (void)printf( "~CNetCleanup() destructor..." ); +#endif // Close sockets BOOST_FOREACH(CNode* pnode, vNodes) if (pnode->hSocket != INVALID_SOCKET) @@ -1926,6 +1994,9 @@ class CNetCleanup #ifdef WIN32 // Shutdown Windows Sockets WSACleanup(); +#endif +#ifdef _MSC_VER + (void)printf( "done\n" ); #endif } } @@ -1975,3 +2046,6 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt pnode->PushInventory(inv); } } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif \ No newline at end of file diff --git a/src/net.h b/src/net.h index 9f3060f991235..7480eec5fb656 100644 --- a/src/net.h +++ b/src/net.h @@ -6,6 +6,8 @@ #define BITCOIN_NET_H #ifdef _MSC_VER + #include "msvc_warnings.push.h" + #include #include #endif @@ -27,6 +29,10 @@ #include "hash.h" #include "bloom.h" +#ifdef _MSC_VER + #include "justincase.h" // for releaseModeAssertionfailure() +#endif + class CNode; class CBlockIndex; extern int nBestHeight; @@ -288,7 +294,18 @@ class CNode int GetRefCount() { +#ifdef _MSC_VER + bool + fTest = (nRefCount >= 0); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nRefCount >= 0); +#endif return nRefCount; } @@ -392,7 +409,18 @@ class CNode void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend) { ENTER_CRITICAL_SECTION(cs_vSend); +#ifdef _MSC_VER + bool + fTest = (0 == ssSend.size()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(ssSend.size() == 0); +#endif ssSend << CMessageHeader(pszCommand, 0); if (fDebug) printf("sending: %s ", pszCommand); @@ -430,7 +458,18 @@ class CNode uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end()); unsigned int nChecksum = 0; memcpy(&nChecksum, &hash, sizeof(nChecksum)); +#ifdef _MSC_VER + bool + fTest = (ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum)); +#endif memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum)); if (fDebug) { @@ -643,4 +682,7 @@ class CTransaction; void RelayTransaction(const CTransaction& tx, const uint256& hash); void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss); +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif diff --git a/src/netbase.cpp b/src/netbase.cpp index 77087e98f5350..3a7abb22359b9 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -3,17 +3,30 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "msvc_warnings.push.h" + + #include "netbase.h" + //#include "util.h" + //#include "sync.h" + //#include "hash.h" + #include "db.h" // for ssize_t +#else #include "netbase.h" #include "util.h" #include "sync.h" #include "hash.h" +#endif #ifndef WIN32 #include #endif #ifdef _MSC_VER -#define ssize_t size_t +//#define ssize_t size_t #endif #include // for to_lower() @@ -96,7 +109,18 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign { if (aiTrav->ai_family == AF_INET) { +#ifdef _MSC_VER + bool + fTest = (aiTrav->ai_addrlen >= sizeof(sockaddr_in)); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in)); +#endif vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr)); } @@ -422,8 +446,18 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe return true; } -bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) { +bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) +{ +#ifdef _MSC_VER + #ifdef _DEBUG + assert(net >= 0 && net < NET_MAX); + #else + if( !(net >= 0 && net < NET_MAX) ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(net >= 0 && net < NET_MAX); +#endif if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5) return false; if (nSocksVersion != 0 && !addrProxy.IsValid()) @@ -433,8 +467,18 @@ bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) { return true; } -bool GetProxy(enum Network net, proxyType &proxyInfoOut) { +bool GetProxy(enum Network net, proxyType &proxyInfoOut) +{ +#ifdef _MSC_VER + #ifdef _DEBUG + assert(net >= 0 && net < NET_MAX); + #else + if( !(net >= 0 && net < NET_MAX) ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(net >= 0 && net < NET_MAX); +#endif LOCK(cs_proxyInfos); if (!proxyInfo[net].second) return false; @@ -994,7 +1038,18 @@ CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNe CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) { +#ifdef _MSC_VER + bool + fTest = (AF_INET == addr.sin_family); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(addr.sin_family == AF_INET); +#endif } #ifdef USE_IPV6 @@ -1141,3 +1196,6 @@ void CService::SetPort(unsigned short portIn) { port = portIn; } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif \ No newline at end of file diff --git a/src/noui.cpp b/src/noui.cpp index c0e00c471553f..31fda6ae11e01 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -4,8 +4,13 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "ui_interface.h" +#ifdef _MSC_VER + //#include "init.h" + //#include "bitcoinrpc.h" +#else #include "init.h" #include "bitcoinrpc.h" +#endif #include diff --git a/src/protocol.cpp b/src/protocol.cpp index 88bbe49afd5a6..594a2e52fdd4c 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -3,6 +3,12 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' +#endif + #include "protocol.h" #include "util.h" #include "netbase.h" diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 11af1abf5d2ee..bd00b829dce20 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -161,6 +161,102 @@ Value getblock(const Array& params, bool fHelp) return blockToJSON(block, pblockindex); } +#ifdef _MSC_VER +Value getcurrentblockandtime(const Array& params, bool fHelp) +{ + if ( + fHelp || + (0 != params.size()) + ) + throw runtime_error( + "getblockcountt\n" + "Returns the number of blocks in the longest block chain and the time of the latest block."); + + CBlockIndex + * pbi = FindBlockByHeight(nBestHeight); + + const uint256 + *pa_hash = pbi->phashBlock; + + if (0 == mapBlockIndex.count(*pa_hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + pbi = mapBlockIndex[*pa_hash]; + + CBlock + block; + + block.ReadFromDisk(pbi); + //___________________________________________ + struct tm + aTimeStruct, + gmTimeStruct; + time_t + tBlock, + mytime; + char + buff[30]; + + tBlock = time_t( block.GetBlockTime() ); + + bool + fIsGMT = true; // the least of all evils + + if( !_localtime64_s( &aTimeStruct, &tBlock ) ) // OK + { + // are we in GMT? + if( !_gmtime64_s( &gmTimeStruct, &tBlock ) ) // OK we can compare + { + if( tBlock != _mkgmtime( &aTimeStruct ) ) + fIsGMT = false; + //else // we are in GMT to begin with + } + //else // _gmtime64_s() errored + } + //else //_localtime64_s() errored + + if( fIsGMT )// for GMT or having errored trying to convert from GMT + { + std::string + strS = strprintf( + "%d %s" + "\n" + "", + int(nBestHeight), + DateTimeStrFormat( + " %Y-%m-%d %H:%M:%S", + block.GetBlockTime() + ).c_str() + ); + return strS; + } + // let's cook up local time + asctime_s( buff, sizeof(buff), &aTimeStruct ); + buff[ 24 ] = '\0'; // let's wipe out the \n + printf( //"Local Time: " + "%s" + "\n" + "" + , buff ); + //___________________________________________ + + std::string + strS = strprintf( + "%d %s (local %s)" + "\n" + "", + int(nBestHeight), + DateTimeStrFormat( + " %Y-%m-%d %H:%M:%S", + block.GetBlockTime() + ).c_str() + , + buff + ); + return strS; +} +#endif + Value gettxoutsetinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index b8b7459634550..4e079966c2d68 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -3,10 +3,21 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "bitcoinrpc.h" + //#include "main.h" + #include "init.h" // for pwalletMain + //#include "db.h" + #include "justincase.h" // for releaseModeAssertionfailure() +#else #include "main.h" #include "db.h" #include "init.h" #include "bitcoinrpc.h" +#endif using namespace json_spirit; using namespace std; diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 99b94ffa3aee0..3db6901d39c87 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -2,7 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include "wallet.h" + //#include "net.h" +#else #include "net.h" +#endif + #include "bitcoinrpc.h" using namespace json_spirit; diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index fb9811b921d99..41876e2ec6b34 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -3,6 +3,23 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\program files\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\libs\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + #include "msvc_warnings.push.h" + + //#include "base58.h" + #include "bitcoinrpc.h" + #include "db.h" + #include "init.h" + //#include "main.h" + //#include "net.h" + //#include "wallet.h" + + #include + #include "justincase.h" // for releaseModeAssertionfailure() +#else #include #include "base58.h" @@ -12,6 +29,7 @@ #include "main.h" #include "net.h" #include "wallet.h" +#endif using namespace std; using namespace boost; @@ -574,3 +592,6 @@ Value sendrawtransaction(const Array& params, bool fHelp) return hashTx.GetHex(); } +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif \ No newline at end of file diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 5fd400c6bbb7e..f2751c1158820 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -3,6 +3,15 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + //#include "wallet.h" + //#include "walletdb.h" + #include "init.h" + #include "bitcoinrpc.h" + //#include "base58.h" + + #include +#else #include #include "wallet.h" @@ -10,6 +19,7 @@ #include "bitcoinrpc.h" #include "init.h" #include "base58.h" +#endif using namespace std; using namespace boost; diff --git a/src/script.cpp b/src/script.cpp index 36e952f3e0938..ad673be858475 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -2,6 +2,27 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifdef _MSC_VER + #include + + #include "msvc_warnings.push.h" + + #include "script.h" + //#include "keystore.h" + //#include "bignum.h" + //#include "key.h" + #include "main.h" + //#include "sync.h" + //#include "util.h" + #include "justincase.h" // for releaseModeAssertionfailure() + + #include + #include + + using namespace std; + using namespace boost; +#else #include #include @@ -15,6 +36,7 @@ using namespace boost; #include "main.h" #include "sync.h" #include "util.h" +#endif bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); @@ -698,7 +720,20 @@ bool EvalScript(vector >& stack, const CScript& script, co case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; case OP_0NOTEQUAL: bn = (bn != bnZero); break; - default: assert(!"invalid opcode"); break; + default: +#ifdef _MSC_VER + bool + fTest = (!"invalid opcode"); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else + assert(!"invalid opcode"); +#endif + break; } popstack(stack); stack.push_back(bn.getvch()); @@ -746,7 +781,21 @@ bool EvalScript(vector >& stack, const CScript& script, co case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; - default: assert(!"invalid opcode"); break; + default: +#ifdef _MSC_VER + bool + fTest = (!"invalid opcode"); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else + assert(!"invalid opcode"); +#endif + assert(!"invalid opcode"); + break; } popstack(stack); popstack(stack); @@ -792,7 +841,40 @@ bool EvalScript(vector >& stack, const CScript& script, co if (stack.size() < 1) return false; valtype& vch = stacktop(-1); +#ifdef _MSC_VER + bool + fTest = false; + + if (0 == vch.size()) + { + fTest = true; + vch.resize( 1 ); + } +#endif valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); +#ifdef _MSC_VER + if (opcode == OP_RIPEMD160) + RIPEMD160(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA1) + SHA1(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA256) + SHA256(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_HASH160) + { + uint160 + hash160 = Hash160(vch); + + memcpy(&vchHash[0], &hash160, sizeof(hash160)); + } + else if (opcode == OP_HASH256) + { + uint256 + hash = Hash(vch.begin(), vch.end()); + + memcpy(&vchHash[0], &hash, sizeof(hash)); + } +#else + if (opcode == OP_RIPEMD160) RIPEMD160(vch.data(), vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) @@ -809,6 +891,7 @@ bool EvalScript(vector >& stack, const CScript& script, co uint256 hash = Hash(vch.begin(), vch.end()); memcpy(&vchHash[0], &hash, sizeof(hash)); } +#endif popstack(stack); stack.push_back(vchHash); } @@ -1172,10 +1255,39 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector n || vSolutionsRet.size()-2 != n) +#ifdef _MSC_VER + if (!vSolutionsRet.empty()) + { + unsigned char + m = vSolutionsRet.front()[0]; + + unsigned char + n = vSolutionsRet.back()[0]; + + if ( + m < 1 || + n < 1 || + m > n || + vSolutionsRet.size()-2 != n + ) + return false; + } + else // what to do? How about, as from below + return false; +#else + unsigned char + m = vSolutionsRet.front()[0]; + + unsigned char + n = vSolutionsRet.back()[0]; + if ( + m < 1 || + n < 1 || + m > n || + vSolutionsRet.size()-2 != n + ) return false; +#endif } return true; } @@ -1499,8 +1611,18 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C // stackCopy cannot be empty here, because if it was the // P2SH HASH <> EQUAL scriptPubKey would be evaluated with // an empty stack and the EvalScript above would return false. +#ifdef _MSC_VER + bool + fTest = (!stackCopy.empty()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(!stackCopy.empty()); - +#endif const valtype& pubKeySerialized = stackCopy.back(); CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stackCopy); @@ -1518,7 +1640,18 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType) { +#ifdef _MSC_VER + bool + fTest = (nIn < txTo.vin.size()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nIn < txTo.vin.size()); +#endif CTxIn& txin = txTo.vin[nIn]; // Leave out the signature from the hash, since a signature can't sign itself. @@ -1553,9 +1686,30 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransa bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType) { +#ifdef _MSC_VER + bool + fTest = (nIn < txTo.vin.size()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nIn < txTo.vin.size()); +#endif CTxIn& txin = txTo.vin[nIn]; +#ifdef _MSC_VER + fTest = (txin.prevout.n < txFrom.vout.size()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(txin.prevout.n < txFrom.vout.size()); +#endif const CTxOut& txout = txFrom.vout[txin.prevout.n]; return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType); @@ -1587,7 +1741,18 @@ static CScript CombineMultisig(CScript scriptPubKey, const CTransaction& txTo, u } // Build a map of pubkey -> signature by matching sigs to pubkeys: +#ifdef _MSC_VER + bool + fTest = (vSolutions.size() > 1); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(vSolutions.size() > 1); +#endif unsigned int nSigsRequired = vSolutions.front()[0]; unsigned int nPubKeys = vSolutions.size()-2; map sigs; @@ -1904,3 +2069,6 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector #include @@ -14,6 +18,10 @@ #include "keystore.h" #include "bignum.h" +#ifdef _MSC_VER + #include "justincase.h" // for releaseModeAssertionfailure() +#endif + class CCoins; class CTransaction; @@ -389,7 +397,15 @@ class CScript : public std::vector { // I'm not sure if this should push the script or concatenate scripts. // If there's ever a use for pushing a script onto a script, delete this member fn +#ifdef _MSC_VER + #ifdef _DEBUG assert(!"Warning: Pushing a CScript onto a CScript with << is probably not intended, use + to concatenate!"); + #else + // what would be OK, if anything? + #endif +#else + assert(!"Warning: Pushing a CScript onto a CScript with << is probably not intended, use + to concatenate!"); +#endif return *this; } @@ -479,12 +495,40 @@ class CScript : public std::vector { if (opcode == OP_0) return 0; +#ifdef _MSC_VER + bool + fTest = ( + (opcode >= OP_1) && + (opcode <= OP_16) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(opcode >= OP_1 && opcode <= OP_16); +#endif return (int)opcode - (int)(OP_1 - 1); } static opcodetype EncodeOP_N(int n) { +#ifdef _MSC_VER + bool + fTest = ( + (n >= 0) && + (n <= 16) + ); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(n >= 0 && n <= 16); +#endif if (n == 0) return OP_0; return (opcodetype)(OP_1+n-1); @@ -639,12 +683,35 @@ class CScriptCompressor void Serialize(Stream &s, int nType, int nVersion) const { std::vector compr; if (Compress(compr)) { - s << CFlatData(compr.data(), compr.data() + compr.size()); +#ifdef _MSC_VER + if( 0 == compr.size() ) + { + compr.resize(1); + // s << CFlatData(&compr[0], &compr[0]); //maybe this was too compatible!! + } + s << CFlatData(&compr[0], &compr[0] + compr.size()); +#else + s << CFlatData(compr.data(), compr.data() + compr.size()); +#endif return; } unsigned int nSize = script.size() + nSpecialScripts; s << VARINT(nSize); +#ifdef _MSC_VER + if( 0 == script.size() ) + { + script.resize(1); + //s << CFlatData(&script[0], &script[0]); //maybe this was too compatible!! + } + //else + #ifdef _DEBUG + int + nSizeofScriptClassElement = sizeof( script[ 0 ] ); // just to see what it can be!? + #endif + s << CFlatData(&script[0], &script[0] + (sizeof(script[0]) * script.size())); +#else s << CFlatData(script.data(), script.data() + script.size()); +#endif } template @@ -653,13 +720,32 @@ class CScriptCompressor s >> VARINT(nSize); if (nSize < nSpecialScripts) { std::vector vch(GetSpecialSize(nSize), 0x00); +#ifdef _MSC_VER + if (0 == vch.size() ) + vch.resize( 1 ); + s >> REF(CFlatData(&vch[0], &vch[0] + vch.size())); +#else s >> REF(CFlatData(vch.data(), vch.data() + vch.size())); +#endif Decompress(nSize, vch); return; } nSize -= nSpecialScripts; script.resize(nSize); +#ifdef _MSC_VER + int + nScriptSize = int( script.size() ); + + if( 0 == nScriptSize ) + script.resize(1); // what else can one do? + + int + nSizeOfElement = int( sizeof(script[0]) ); // just to see if it is ever >1 ? + + s >> REF(CFlatData(&script[0], &script[0] + (nSizeOfElement * script.size()))); +#else s >> REF(CFlatData(script.data(), script.data() + script.size())); +#endif } }; @@ -682,4 +768,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C // combine them intelligently and return the result. CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif diff --git a/src/serialize.h b/src/serialize.h index 48e8f3a16ed64..614e5128e4797 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -5,6 +5,10 @@ #ifndef BITCOIN_SERIALIZE_H #define BITCOIN_SERIALIZE_H +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include #include #include @@ -22,6 +26,10 @@ #include "allocators.h" #include "version.h" +#ifdef _MSC_VER + #include "justincase.h" // for releaseModeAssertionfailure() +#endif + typedef long long int64; typedef unsigned long long uint64; @@ -905,7 +913,18 @@ class CDataStream void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) { +#ifdef _MSC_VER + bool + fTest = (last - first >= 0); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(last - first >= 0); +#endif if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room @@ -919,7 +938,18 @@ class CDataStream #if !defined(_MSC_VER) || _MSC_VER >= 1300 void insert(iterator it, const char* first, const char* last) { +#ifdef _MSC_VER + bool + fTest = (last - first >= 0); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(last - first >= 0); +#endif if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room @@ -1013,7 +1043,18 @@ class CDataStream CDataStream& read(char* pch, int nSize) { // Read from the beginning of the buffer +#ifdef _MSC_VER + bool + fTest = (nSize >= 0); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nSize >= 0); +#endif unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) { @@ -1036,7 +1077,18 @@ class CDataStream CDataStream& ignore(int nSize) { // Ignore from the beginning of the buffer +#ifdef _MSC_VER + bool + fTest = (nSize >= 0); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nSize >= 0); +#endif unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) { @@ -1056,7 +1108,18 @@ class CDataStream CDataStream& write(const char* pch, int nSize) { // Write to the end of the buffer +#ifdef _MSC_VER + bool + fTest = (nSize >= 0); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(nSize >= 0); +#endif vch.insert(vch.end(), pch, pch + nSize); return (*this); } @@ -1366,4 +1429,7 @@ class CBufferedFile } }; +#ifdef _MSC_VER + #include "msvc_warnings.pop.h" +#endif #endif diff --git a/src/sync.cpp b/src/sync.cpp index 1ac4403beb1f7..61557a864e381 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -2,8 +2,20 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include // this gets rid of the + // ...\microsoft visual studio 8\vc\include\stdint.h(244) : warning C4005: 'INTMAX_C' : macro redefinition + // ...\boost_1_53_0\boost\cstdint.hpp(423) : see previous definition of 'INTMAX_C' + + #define DEBUG_LOCKORDER + #define DEBUG_LOCKCONTENTION + //#include "sync.h" + #include "util.h" + #include "sync.h" +#else #include "sync.h" #include "util.h" +#endif #include diff --git a/src/txdb.cpp b/src/txdb.cpp index 695636fb4c503..dbe4edc2381fd 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -152,7 +152,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) { } pcursor->Next(); } catch (std::exception &e) { - return error("%s() : deserialize error", BOOST_CURRENT_FUNCTION); + return error("%s() : deserialize error", __PRETTY_FUNCTION__); } } delete pcursor; @@ -193,10 +193,22 @@ bool CBlockTreeDB::LoadBlockIndexGuts() ssKeySet << make_pair('b', uint256(0)); pcursor->Seek(ssKeySet.str()); +#ifdef _MSC_VER + int + nCount = 0; + int64 + n64MilliSecondsTotal, + n64MilliSecondsStart, + n64MilliSecondsNow; + + n64MilliSecondsStart = GetTimeMillis(); +#endif // Load mapBlockIndex - while (pcursor->Valid()) { + while (pcursor->Valid()) + { boost::this_thread::interruption_point(); - try { + try + { leveldb::Slice slKey = pcursor->key(); CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); char chType; @@ -223,21 +235,59 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nTx = diskindex.nTx; // Watch for genesis block - if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) - pindexGenesisBlock = pindexNew; - +#ifdef _MSC_VER + if (0 == diskindex.nHeight ) // this must be a faster test? +#endif + if (pindexGenesisBlock == NULL && + diskindex.GetBlockHash() == hashGenesisBlock + ) + { + pindexGenesisBlock = pindexNew; +#ifdef _MSC_VER + if( fPrintToConsole ) + (void)printf( + " Found block 0" + "\n" + ); +#endif + } if (!pindexNew->CheckIndex()) return error("LoadBlockIndex() : CheckIndex failed: %s", pindexNew->ToString().c_str()); pcursor->Next(); +#ifdef _MSC_VER + ++nCount; + if( + fPrintToConsole && + nCount && + ( !( nCount % 10 ) ) + ) // show some activity + (void)printf( + "\r" + "%6d " + "", + (diskindex.nHeight)/* / 10 */ + ); +#endif } else { break; // if shutdown requested or finished loading block index } } catch (std::exception &e) { - return error("%s() : deserialize error", BOOST_CURRENT_FUNCTION); + return error("%s() : deserialize error", __PRETTY_FUNCTION__); } } delete pcursor; - +#ifdef _MSC_VER + (void)printf( "\n" ); + n64MilliSecondsNow = GetTimeMillis(); + n64MilliSecondsTotal = n64MilliSecondsNow - n64MilliSecondsStart; + + (void)printf( "%d iterations in %.3f secs" + "\n" + "", + nCount, + n64MilliSecondsTotal / 1000.0 + ); +#endif return true; } diff --git a/src/uint256.h b/src/uint256.h index 980980e2f77b3..bce791415d5df 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -5,6 +5,10 @@ #ifndef BITCOIN_UINT256_H #define BITCOIN_UINT256_H +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif + #include #include #include @@ -785,4 +789,7 @@ inline int Testuint256AdHoc(std::vector vArg) #endif +#ifdef _MSC_VER + #include "msvc_warnings.push.h" +#endif #endif diff --git a/src/util.cpp b/src/util.cpp index 00cd1c92f4078..711e06ab9fc27 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -3,6 +3,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef _MSC_VER + #include +#endif + #ifndef WIN32 // for posix_fallocate #ifdef __linux__ @@ -13,10 +17,17 @@ #include #endif +#ifdef _MSC_VER + //#include "util.h" + #include "sync.h" + //#include "version.h" + #include "ui_interface.h" +#else #include "util.h" #include "sync.h" #include "version.h" #include "ui_interface.h" +#endif #include #include // for to_lower() #include // for startswith() and endswith() @@ -223,9 +234,27 @@ static boost::mutex* mutexDebugLog = NULL; static void DebugPrintInit() { +#ifdef _MSC_VER + bool + fTest = (fileout == NULL); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif + + fTest = (mutexDebugLog == NULL); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(fileout == NULL); assert(mutexDebugLog == NULL); - +#endif boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; fileout = fopen(pathDebug.string().c_str(), "a"); if (fileout) setbuf(fileout, NULL); // unbuffered @@ -247,7 +276,40 @@ int OutputDebugStringF(const char* pszFormat, ...) else if (!fPrintToDebugger) { static bool fStartedNewLine = true; +#ifdef _MSC_VER + // call_once() fails misrerably here when + // DEBUG_LOCKCONTENTION &/or DEBUG_LOCKORDER and debug + // are defined. The file is never opened and no data is recorded. + + // The problem is that DebugPrintInit() calls GetDataDir() + // which calls Lock() which calls push_lock() and if (fDebug) + // calls printf() which recurses OutputDebugStringF(), ... and + // boost::call_once() just mnakes it all worse! + // + // This is observed on Windows compiling with gcc or MSVC++!! + // The code below does work though! I believe the first printf() + // may be absorbed in that one recursion? I didn't test it. + // + // The upshot of all of this is that the provisio in .../doc/coding.md + // where it states in the + // Locking/mutex usage notes + // ... Compile with -DDEBUG_LOCKORDER to get lock order + //inconsistencies reported in the debug.log file. + // + // This is impossible to obtain with the boost::call_once() code + // which goes back to at least bitcoind 0.8.3 + + static bool + fAvoidBoostOnceWithAbool = true; + + if( fAvoidBoostOnceWithAbool ) + { + fAvoidBoostOnceWithAbool = false; + DebugPrintInit(); + } +#else boost::call_once(&DebugPrintInit, debugPrintInitFlag); +#endif if (fileout == NULL) return ret; @@ -313,8 +375,14 @@ string vstrprintf(const char *format, va_list ap) int ret; loop { +#ifndef _MSC_VER va_list arg_ptr; va_copy(arg_ptr, ap); +#else + va_list + arg_ptr = ap; +#endif + #ifdef WIN32 ret = _vsnprintf(p, limit, format, arg_ptr); #else @@ -541,12 +609,18 @@ void ParseParameters(int argc, const char* const argv[]) { mapArgs.clear(); mapMultiArgs.clear(); - for (int i = 1; i < argc; i++) + for (int i = 1; i < argc; ++i) { - std::string str(argv[i]); - std::string strValue; - size_t is_index = str.find('='); - if (is_index != std::string::npos) + std::string + str(argv[i]); + + std::string + strValue; + + size_t + is_index = str.find('='); + + if (is_index != std::string::npos) // i.e. there is an '=' { strValue = str.substr(is_index+1); str = str.substr(0, is_index); @@ -556,9 +630,14 @@ void ParseParameters(int argc, const char* const argv[]) if (boost::algorithm::starts_with(str, "/")) str = "-" + str.substr(1); #endif - if (str[0] != '-') - break; +#ifdef _MSC_VER + if ('-' != str[0]) + continue; +#else + if (str[0] != '-') + break; // why? This forces all -arg=xxx to be first +#endif mapArgs[str] = strValue; mapMultiArgs[str].push_back(strValue); } @@ -566,7 +645,8 @@ void ParseParameters(int argc, const char* const argv[]) // New 0.6 features: BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs) { - string name = entry.first; + string + name = entry.first; // interpret --foo as -foo (as long as both are not set) if (name.find("--") == 0) @@ -761,6 +841,10 @@ vector DecodeBase64(const char* p, bool* pfInvalid) string DecodeBase64(const string& str) { vector vchRet = DecodeBase64(str.c_str()); +#ifdef _MSC_VER + if( vchRet.empty() ) // can one return the nul string? + return string( "" ); +#endif return string((const char*)&vchRet[0], vchRet.size()); } @@ -948,6 +1032,10 @@ vector DecodeBase32(const char* p, bool* pfInvalid) string DecodeBase32(const string& str) { vector vchRet = DecodeBase32(str.c_str()); +#ifdef _MSC_VER + if( vchRet.empty() ) + return string( "" ); +#endif return string((const char*)&vchRet[0], vchRet.size()); } @@ -1092,8 +1180,11 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) boost::filesystem::path GetConfigFile() { - boost::filesystem::path pathConfigFile(GetArg("-conf", "bitcoin.conf")); - if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; + boost::filesystem::path + pathConfigFile(GetArg("-conf", "bitcoin.conf")); + + if (!pathConfigFile.is_complete()) + pathConfigFile = GetDataDir(false) / pathConfigFile; return pathConfigFile; } diff --git a/src/util.h b/src/util.h index a190a3b5da85e..270b823028ad5 100644 --- a/src/util.h +++ b/src/util.h @@ -490,7 +490,18 @@ template class CMedianFilter T median() const { int size = vSorted.size(); +#ifdef _MSC_VER + bool + fTest = (size>0); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(size>0); +#endif if(size & 1) // Odd number of elements { return vSorted[size/2]; diff --git a/src/wallet.cpp b/src/wallet.cpp index d030ab1834193..9be0ac4efe005 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -8,6 +8,9 @@ #include "crypter.h" #include "ui_interface.h" #include "base58.h" +#ifdef _MSC_VER + #include "justincase.h" // for releaseModeAssertionfailure() +#endif #include using namespace std; @@ -267,7 +270,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) { if (fFileBacked) pwalletdbEncryption->TxnAbort(); +#ifdef _MSC_VER + // a rather crude thing to do, don't you think? Can't we shutdown gracefully? + // perhaps just + return false; // looking at what encryptwallet() in rpcwallet.cpp does +#else exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet. +#endif } // Encryption was introduced in version 0.4.0 @@ -276,7 +285,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) if (fFileBacked) { if (!pwalletdbEncryption->TxnCommit()) +#ifdef _MSC_VER + return false; // looking at what encryptwallet() in rpcwallet.cpp does +#else exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. +#endif delete pwalletdbEncryption; pwalletdbEncryption = NULL; @@ -765,27 +778,153 @@ bool CWalletTx::WriteToDisk() return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); } +#ifdef _MSC_VER +//_____________________________________________________________________________ +static void + DoRescanProgress( int nCount, int nTotalToScan, int64 n64MsStartTime ) +{ + int64 + n64SecondsEstimatedTotalTime, + n64MsEstimatedTotalTime, + n64MsDeltaTime; + + if( + (0 == (nCount % 10) ) // every 10th time + ) + { + if( 0 == nCount ) // first time + { + (void)printf( + "%6d " + "" + , nCount + ); + } + else // all the next times + { + n64SecondsEstimatedTotalTime = 0; + if( + (0 == (nCount % 100) ) // every 100th time (every 10th next time) + ) + { // let's estimate the time remaining too! + n64MsDeltaTime = GetTimeMillis() - n64MsStartTime; + // we have done nCount / nTotalToScan th of them in n64MsDeltaTime + // so total time in ms ~ n64MsDeltaTime * nTotalToScan / nCount + n64MsEstimatedTotalTime = n64MsDeltaTime * nTotalToScan / nCount; + // time (seconds) remaining is + n64SecondsEstimatedTotalTime = + ( n64MsEstimatedTotalTime + n64MsStartTime - GetTimeMillis() ) / 1000; + } + (void)printf( + "%6d " + "%2.2f%% " + "" + , nCount + , floorf( float(nCount * 10000.0 / nTotalToScan) ) / 100 + ); + if( 0 != n64SecondsEstimatedTotalTime ) + { + const int64 + nSecondsPerMinute = 60, + nMinutesPerHour = 60; + int64 + nSeconds = 0, + nMinutes = 0, + nHours = 0; + + if( n64SecondsEstimatedTotalTime >= nSecondsPerMinute ) + { // there are minutes to go + nSeconds = n64SecondsEstimatedTotalTime % nSecondsPerMinute; + nMinutes = n64SecondsEstimatedTotalTime / nSecondsPerMinute; + if( nMinutes >= nMinutesPerHour ) // there are hours to go + { + nHours = nMinutes / nMinutesPerHour; + nMinutes %= nMinutesPerHour; + (void)printf( + "~%d:%02d:%02d hrs:min:sec" + "" + , + (int)nHours, + (int)nMinutes, + (int)nSeconds + ); + } + else // there are only minutes + { + (void)printf( + "~%2d:%02d min:sec " + "\r" + "" + , + (int)nMinutes, + (int)nSeconds + ); + } + } + else // there are only seconds + { + nSeconds = n64SecondsEstimatedTotalTime; + (void)printf( + "~%2d sec " + "" + , + (int)nSeconds + ); + } + } + } + (void)printf( "\r" ); + } +} +//_____________________________________________________________________________ +#endif // Scan the block chain (starting in pindexStart) for transactions // from or to us. If fUpdate is true, found transactions that already // exist in the wallet will be updated. -int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) +int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate +#ifdef _MSC_VER + , int nTotalToScan +#endif + ) { - int ret = 0; + int + ret = 0; - CBlockIndex* pindex = pindexStart; + CBlockIndex + * pindex = pindexStart; { +#ifdef _MSC_VER + int + nCount = 0; + + int64 + n64MsStartTime = GetTimeMillis(); +#endif LOCK(cs_wallet); + while (pindex) { - CBlock block; + CBlock + block; + block.ReadFromDisk(pindex); BOOST_FOREACH(CTransaction& tx, block.vtx) { if (AddToWalletIfInvolvingMe(tx.GetHash(), tx, &block, fUpdate)) - ret++; + ++ret; } pindex = pindex->pnext; +#ifdef _MSC_VER + ++nCount; + if (fPrintToConsole) + DoRescanProgress( nCount, nTotalToScan, n64MsStartTime ); + } + if (fPrintToConsole) // this could be a progress bar, % meter etc. + (void)printf( "\n" );// but we would need another parameter of the total + // # of blocks to scan +#else } +#endif } return ret; } @@ -1234,7 +1373,17 @@ bool CWallet::CreateTransaction(const vector >& vecSend, // Reserve a new key pair from key pool CPubKey vchPubKey; bool b = reservekey.GetReservedKey(vchPubKey); +#ifdef _MSC_VER + #ifdef _DEBUG + assert(b); + #else + if( !b ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(b); // should never fail, as we just unlocked + // Wow! An assertion done correctly. I'm amazed!! +#endif // Fill a vout to ourself // TODO: pass in scriptChange instead of reservekey so @@ -1580,7 +1729,18 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) throw runtime_error("ReserveKeyFromKeyPool() : read failed"); if (!HaveKey(keypool.vchPubKey.GetID())) throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); +#ifdef _MSC_VER + bool + fTest = (keypool.vchPubKey.IsValid()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(keypool.vchPubKey.IsValid()); +#endif printf("keypool reserve %"PRI64d"\n", nIndex); } } @@ -1804,7 +1964,18 @@ bool CReserveKey::GetReservedKey(CPubKey& pubkey) return false; } } +#ifdef _MSC_VER + bool + fTest = (vchPubKey.IsValid()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(vchPubKey.IsValid()); +#endif pubkey = vchPubKey; return true; } @@ -1837,7 +2008,18 @@ void CWallet::GetAllReserveKeys(set& setAddress) CKeyPool keypool; if (!walletdb.ReadPool(id, keypool)) throw runtime_error("GetAllReserveKeyHashes() : read failed"); +#ifdef _MSC_VER + bool + fTest = (keypool.vchPubKey.IsValid()); + #ifdef _DEBUG + assert(fTest); + #else + if( !fTest ) + releaseModeAssertionfailure( __FILE__, __LINE__, __PRETTY_FUNCTION__ ); + #endif +#else assert(keypool.vchPubKey.IsValid()); +#endif CKeyID keyID = keypool.vchPubKey.GetID(); if (!HaveKey(keyID)) throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); diff --git a/src/wallet.h b/src/wallet.h index dcba4675ebe6d..d2148e8ea80d6 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -172,7 +172,11 @@ class CWallet : public CCryptoKeyStore bool AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false); bool EraseFromWallet(uint256 hash); void WalletUpdateSpent(const CTransaction& prevout); +#ifdef _MSC_VER + int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false, int nTotalNumberofBlocksToScan = 0); +#else int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); +#endif void ReacceptWalletTransactions(); void ResendWalletTransactions(); int64 GetBalance() const;