Gavin Andresen's JSON-RPC HTTP authentication,
authorSatoshi Nakamoto <satoshin@gmx.com>
Mon, 26 Jul 2010 17:40:05 +0000 (17:40 +0000)
committerGavin Andresen <gavinandresen@gmail.com>
Mon, 26 Jul 2010 17:40:05 +0000 (17:40 +0000)
faster initial block download
-- version 0.3.3

12 files changed:
db.cpp
db.h
main.cpp
main.h
makefile.unix
rpc.cpp
serialize.h
setup.nsi
ui.cpp
uibase.h
uiproject.fbp
util.cpp

diff --git a/db.cpp b/db.cpp
index a44ced3..238f5b7 100644 (file)
--- 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<pair<int, CBlockIndex*> > 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 5a2db0c..96d0973 100644 (file)
--- a/db.h
+++ b/db.h
@@ -16,7 +16,7 @@ extern map<string, string> mapAddressBook;
 extern CCriticalSection cs_mapAddressBook;
 extern vector<unsigned char> 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);
index 93722af..45ad06f 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -24,6 +24,7 @@ map<uint256, CBlockIndex*> 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<int> 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<CWalletTx*>& setCoinsRet)
 {
@@ -2858,9 +2883,14 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
 
     CRITICAL_BLOCK(cs_mapWallet)
     {
-        for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
-        {
-            CWalletTx* pcoin = &(*it).second;
+       vector<CWalletTx*> vCoins;
+       vCoins.reserve(mapWallet.size());
+       for (map<uint256, CWalletTx>::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 9a9bdf2..47e2351 100644 (file)
--- a/main.h
+++ b/main.h
@@ -32,6 +32,7 @@ extern map<uint256, CBlockIndex*> 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);
index 8b6441e..74d460c 100644 (file)
@@ -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 f0c44e8..5c3e64a 100644 (file)
--- 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
 }
 
index 0ee4da1..7472ec9 100644 (file)
@@ -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 = "";
 
 
 
index 4ab4be3..9a06832 100644 (file)
--- 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 c184fc4..2002dd6 100644 (file)
--- 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();
index 6eefe21..2c5e2fe 100644 (file)
--- 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();
        
 };
index 54e010b..3f55190 100644 (file)
             <property name="minimum_size"></property>
             <property name="name">CAboutDialogBase</property>
             <property name="pos"></property>
-            <property name="size">532,329</property>
+            <property name="size">532,333</property>
             <property name="style">wxDEFAULT_DIALOG_STYLE</property>
             <property name="subclass"></property>
             <property name="title">About Bitcoin</property>
index 8569397..1c9f861 100644 (file)
--- a/util.cpp
+++ b/util.cpp
@@ -642,7 +642,7 @@ void ReadConfigFile(map<string, string>& mapSettingsRet,
 
     set<string> 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