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;