diff --git a/db.cpp b/db.cpp index a44ced3ce..238f5b7f3 100644 --- a/db.cpp +++ b/db.cpp @@ -130,7 +130,14 @@ void CDB::Close() vTxn.front()->abort(); vTxn.clear(); pdb = NULL; - dbenv.txn_checkpoint(0, 0, 0); + + // Flush database activity from memory pool to disk log + unsigned int nMinutes = 0; + if (strFile == "addr.dat") + nMinutes = 2; + if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0) + nMinutes = 1; + dbenv.txn_checkpoint(0, nMinutes, 0); CRITICAL_BLOCK(cs_db) --mapFileUseCount[strFile]; @@ -357,11 +364,12 @@ CBlockIndex* InsertBlockIndex(uint256 hash) bool CTxDB::LoadBlockIndex() { - // Get cursor + // Get database cursor Dbc* pcursor = GetCursor(); if (!pcursor) return false; + // Load mapBlockIndex unsigned int fFlags = DB_SET_RANGE; loop { @@ -398,7 +406,7 @@ bool CTxDB::LoadBlockIndex() pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; - // Watch for genesis block and best block + // Watch for genesis block if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) pindexGenesisBlock = pindexNew; } @@ -409,17 +417,33 @@ bool CTxDB::LoadBlockIndex() } pcursor->close(); + // Calculate bnChainWork + vector > vSortedByHeight; + vSortedByHeight.reserve(mapBlockIndex.size()); + foreach(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) + { + CBlockIndex* pindex = item.second; + vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); + } + sort(vSortedByHeight.begin(), vSortedByHeight.end()); + foreach(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) + { + CBlockIndex* pindex = item.second; + pindex->bnChainWork = (pindex->pprev ? pindex->pprev->bnChainWork : 0) + pindex->GetBlockWork(); + } + + // Load hashBestChain pointer to end of best chain if (!ReadHashBestChain(hashBestChain)) { if (pindexGenesisBlock == NULL) return true; - return error("CTxDB::LoadBlockIndex() : hashBestChain not found"); + return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); } - if (!mapBlockIndex.count(hashBestChain)) - return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found"); + return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; + bnBestChainWork = pindexBest->bnChainWork; printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); return true; diff --git a/db.h b/db.h index 5a2db0cca..96d0973d8 100644 --- a/db.h +++ b/db.h @@ -16,7 +16,7 @@ extern map mapAddressBook; extern CCriticalSection cs_mapAddressBook; extern vector vchDefaultKey; extern bool fClient; - +extern int nBestHeight; extern unsigned int nWalletDBUpdated; @@ -210,7 +210,7 @@ public: if (!pdb) return false; DbTxn* ptxn = NULL; - int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0); + int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC); if (!ptxn || ret != 0) return false; vTxn.push_back(ptxn); diff --git a/main.cpp b/main.cpp index 93722aff8..45ad06f93 100644 --- a/main.cpp +++ b/main.cpp @@ -24,6 +24,7 @@ map mapBlockIndex; const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; +CBigNum bnBestChainWork = 0; uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; int64 nTimeBestReceived = 0; @@ -848,6 +849,23 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast) return bnNew.GetCompact(); } +vector vStartingHeight; +void AddStartingHeight(int nStartingHeight) +{ + if (nStartingHeight != -1) + { + vStartingHeight.push_back(nStartingHeight); + sort(vStartingHeight.begin(), vStartingHeight.end()); + } +} + +bool IsInitialBlockDownload() +{ + int nMedian = 69000; + if (vStartingHeight.size() >= 5) + nMedian = vStartingHeight[vStartingHeight.size()/2]; + return nBestHeight < nMedian-1000; +} @@ -1208,13 +1226,14 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) pindexNew->pprev = (*miPrev).second; pindexNew->nHeight = pindexNew->pprev->nHeight + 1; } + pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork(); CTxDB txdb; txdb.TxnBegin(); txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); // New best - if (pindexNew->nHeight > nBestHeight) + if (pindexNew->bnChainWork > bnBestChainWork) { if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) { @@ -1253,6 +1272,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) hashBestChain = hash; pindexBest = pindexNew; nBestHeight = pindexBest->nHeight; + bnBestChainWork = pindexNew->bnChainWork; nTimeBestReceived = GetTime(); nTransactionsUpdated++; printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); @@ -1900,6 +1920,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } AddTimeData(pfrom->addr.ip, nTime); + AddStartingHeight(pfrom->nStartingHeight); // Change version if (pfrom->nVersion >= 209) @@ -2845,6 +2866,10 @@ int64 GetBalance() } +int GetRandInt(int nMax) +{ + return GetRand(nMax); +} bool SelectCoins(int64 nTargetValue, set& setCoinsRet) { @@ -2858,9 +2883,14 @@ bool SelectCoins(int64 nTargetValue, set& setCoinsRet) CRITICAL_BLOCK(cs_mapWallet) { - for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) - { - CWalletTx* pcoin = &(*it).second; + vector vCoins; + vCoins.reserve(mapWallet.size()); + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + vCoins.push_back(&(*it).second); + random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); + + foreach(CWalletTx* pcoin, vCoins) + { if (!pcoin->IsFinal() || pcoin->fSpent) continue; int64 n = pcoin->GetCredit(); diff --git a/main.h b/main.h index 9a9bdf29c..47e23511a 100644 --- a/main.h +++ b/main.h @@ -32,6 +32,7 @@ extern map mapBlockIndex; extern const uint256 hashGenesisBlock; extern CBlockIndex* pindexGenesisBlock; extern int nBestHeight; +extern CBigNum bnBestChainWork; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; @@ -78,6 +79,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); void BitcoinMiner(); +bool IsInitialBlockDownload(); @@ -986,11 +988,14 @@ public: // Flush stdio buffers and commit to disk before returning fflush(fileout); + if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0) + { #ifdef __WXMSW__ - _commit(_fileno(fileout)); + _commit(_fileno(fileout)); #else - fsync(fileno(fileout)); + fsync(fileno(fileout)); #endif + } return true; } @@ -1072,6 +1077,7 @@ public: unsigned int nFile; unsigned int nBlockPos; int nHeight; + CBigNum bnChainWork; // block header int nVersion; @@ -1089,6 +1095,7 @@ public: nFile = 0; nBlockPos = 0; nHeight = 0; + bnChainWork = 0; nVersion = 0; hashMerkleRoot = 0; @@ -1105,6 +1112,7 @@ public: nFile = nFileIn; nBlockPos = nBlockPosIn; nHeight = 0; + bnChainWork = 0; nVersion = block.nVersion; hashMerkleRoot = block.hashMerkleRoot; @@ -1118,6 +1126,11 @@ public: return *phashBlock; } + CBigNum GetBlockWork() const + { + return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1); + } + bool IsInMainChain() const { return (pnext || this == pindexBest); diff --git a/makefile.unix b/makefile.unix index 8b6441ef1..74d460c96 100644 --- a/makefile.unix +++ b/makefile.unix @@ -21,7 +21,7 @@ WXLIBS= \ LIBS= \ -Wl,-Bstatic \ - -l boost_system -l boost_filesystem -l boost_program_options \ + -l boost_system -l boost_filesystem -l boost_program_options \ -l db_cxx \ -l crypto \ -Wl,-Bdynamic \ diff --git a/rpc.cpp b/rpc.cpp index f0c44e8b3..5c3e64a43 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -39,7 +39,7 @@ void PrintConsole(const char* format, ...) #if defined(__WXMSW__) && wxUSE_GUI MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION); #else - fprintf(stdout, buffer); + fprintf(stdout, "%s", buffer); #endif } diff --git a/serialize.h b/serialize.h index 0ee4da140..7472ec9df 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 302; -static const char* pszSubVer = ".2"; +static const int VERSION = 303; +static const char* pszSubVer = ""; diff --git a/setup.nsi b/setup.nsi index 4ab4be365..9a068321d 100644 --- a/setup.nsi +++ b/setup.nsi @@ -7,7 +7,7 @@ RequestExecutionLevel highest # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.3.2 +!define VERSION 0.3.3 !define COMPANY "Bitcoin project" !define URL http://www.bitcoin.org/ @@ -42,12 +42,12 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile bitcoin-0.3.2-win32-setup.exe +OutFile bitcoin-0.3.3-win32-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on ShowInstDetails show -VIProductVersion 0.3.2.0 +VIProductVersion 0.3.3.0 VIAddVersionKey ProductName Bitcoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}" diff --git a/ui.cpp b/ui.cpp index c184fc495..2002dd660 100644 --- a/ui.cpp +++ b/ui.cpp @@ -1614,6 +1614,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d beta"), VERSION/10000, (VERSION/100)%100, VERSION%100)); + //m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d%s beta"), VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer)); // Change (c) into UTF-8 or ANSI copyright symbol wxString str = m_staticTextMain->GetLabel(); diff --git a/uibase.h b/uibase.h index 6eefe2186..2c5e2feae 100644 --- a/uibase.h +++ b/uibase.h @@ -227,7 +227,7 @@ class CAboutDialogBase : public wxDialog public: wxStaticText* m_staticTextVersion; - CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); + CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,333 ), long style = wxDEFAULT_DIALOG_STYLE ); ~CAboutDialogBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 54e010bdd..3f5519094 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -2866,7 +2866,7 @@ CAboutDialogBase - 532,329 + 532,333 wxDEFAULT_DIALOG_STYLE About Bitcoin diff --git a/util.cpp b/util.cpp index 85693977d..1c9f86141 100644 --- a/util.cpp +++ b/util.cpp @@ -642,7 +642,7 @@ void ReadConfigFile(map& mapSettingsRet, set setOptions; setOptions.insert("*"); - + for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) { // Don't overwrite existing settings so command line settings override bitcoin.conf @@ -732,7 +732,7 @@ void AddTimeData(unsigned int ip, int64 nTime) sort(vTimeOffsets.begin(), vTimeOffsets.end()); int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; nTimeOffset = nMedian; - if ((nMedian > 0 ? nMedian : -nMedian) > 36 * 60 * 60) + if ((nMedian > 0 ? nMedian : -nMedian) > 70 * 60) { // Only let other nodes change our clock so far before we // go to the NTP servers