No more boost format function in code
[novacoin.git] / src / init.cpp
index 1eb28a5..90bf8de 100644 (file)
@@ -8,9 +8,9 @@
 #include "net.h"
 #include "init.h"
 #include "util.h"
+#include "ipcollector.h"
 #include "ui_interface.h"
 #include "checkpoints.h"
-#include <boost/format.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/filesystem/convenience.hpp>
@@ -37,7 +37,6 @@ enum Checkpoints::CPMode CheckpointsMode;
 
 // Ping and address broadcast intervals
 extern int64_t nPingInterval;
-extern int64_t nBroadcastInterval;
 extern int64_t nReserveBalance;
 
 //////////////////////////////////////////////////////////////////////////////
@@ -81,7 +80,7 @@ void Shutdown(void* parg)
             fTaken = true;
         }
     }
-    static bool fExit;
+    volatile static bool fExit;
     if (fFirstThread)
     {
         fShutdown = true;
@@ -190,12 +189,11 @@ bool AppInit(int argc, char* argv[])
 extern void noui_connect();
 int main(int argc, char* argv[])
 {
-    bool fRet = false;
 
     // Connect bitcoind signal handlers
     noui_connect();
 
-    fRet = AppInit(argc, argv);
+    bool fRet = AppInit(argc, argv);
 
     if (fRet && fDaemon)
         return 0;
@@ -252,7 +250,7 @@ std::string HelpMessage()
         "  -connect=<ip>          " + _("Connect only to the specified node(s)") + "\n" +
         "  -seednode=<ip>         " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" +
         "  -externalip=<ip>       " + _("Specify your own public address") + "\n" +
-        "  -onlynet=<net>         " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n" +
+        "  -onlynet=<net>         " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Onion)") + "\n" +
         "  -discover              " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" +
         "  -irc                   " + _("Find peers using internet relay chat (default: 1)") + "\n" +
         "  -listen                " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" +
@@ -263,13 +261,6 @@ std::string HelpMessage()
         "  -bantime=<n>           " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
         "  -maxreceivebuffer=<n>  " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)") + "\n" +
         "  -maxsendbuffer=<n>     " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)") + "\n" +
-#ifdef USE_UPNP
-#if USE_UPNP
-        "  -upnp                  " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n" +
-#else
-        "  -upnp                  " + _("Use UPnP to map the listening port (default: 0)") + "\n" +
-#endif
-#endif
         "  -detachdb              " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
 
 #ifdef DB_LOG_IN_MEMORY
@@ -277,7 +268,7 @@ std::string HelpMessage()
 #endif
 
         "  -paytxfee=<amt>        " + _("Fee per KB to add to transactions you send") + "\n" +
-        "  -mininput=<amt>        " + str(boost::format(_("When creating transactions, ignore inputs with value less than this (default: %s)")) % FormatMoney(MIN_TXOUT_AMOUNT)) + "\n" +
+        "  -mininput=<amt>        " + ((string)("When creating transactions, ignore inputs with value less than this (default: ") + FormatMoney(MIN_TXOUT_AMOUNT) + ")") + "\n" +
 #ifdef QT_GUI
         "  -server                " + _("Accept command line and JSON-RPC commands") + "\n" +
 #endif
@@ -300,13 +291,14 @@ std::string HelpMessage()
         "  -rpcconnect=<ip>       " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
         "  -blocknotify=<cmd>     " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" +
         "  -walletnotify=<cmd>    " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n" +
+        "  -peercollector=<cmd>     " + _("Execute command to collect peer addresses") + "\n" +
         "  -confchange            " + _("Require a confirmations for change (default: 0)") + "\n" +
         "  -upgradewallet         " + _("Upgrade wallet to latest format") + "\n" +
         "  -keypool=<n>           " + _("Set key pool size to <n> (default: 100)") + "\n" +
         "  -rescan                " + _("Rescan the block chain for missing wallet transactions") + "\n" +
         "  -zapwallettxes         " + _("Clear list of wallet transactions (diagnostic tool; implies -rescan)") + "\n" +
         "  -salvagewallet         " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\n" +
-        "  -checkblocks=<n>       " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
+        "  -checkblocks=<n>       " + _("How many blocks to check at startup (default: 192, 0 = all)") + "\n" +
         "  -checklevel=<n>        " + _("How thorough the block verification is (0-6, default: 1)") + "\n" +
         "  -par=N                 " + _("Set the number of script verification threads (1-16, 0=auto, default: 0)") + "\n" +
         "  -loadblock=<file>      " + _("Imports blocks from external blk000?.dat file") + "\n" +
@@ -325,9 +317,39 @@ std::string HelpMessage()
     return strUsage;
 }
 
-/** Initialize bitcoin.
- *  @pre Parameters should be parsed and config file should be read.
- */
+bool DropBlockIndex()
+{
+    try
+    {
+#ifdef USE_LEVELDB
+        filesystem::path directory = GetDataDir() / "txleveldb";
+        filesystem::remove_all(directory); // remove directory
+#else
+        filesystem::path indexFile = GetDataDir() / "blkindex.dat";
+        filesystem::remove(indexFile); // remove index file
+#endif
+
+        unsigned int nFile = 1;
+        for ( ; ; )
+        {
+            filesystem::path strBlockFile = GetDataDir() / strprintf("blk%04u.dat", nFile);
+            // Break if no such file
+            if( !filesystem::exists( strBlockFile ) )
+                break;
+            filesystem::remove(strBlockFile);
+            nFile++;
+        }
+        return true;
+    }
+    catch(const std::exception&)
+    {
+        // TODO: report error here
+        return false;
+    }
+}
+
+// Initialize bitcoin.
+//  @pre Parameters should be parsed and config file should be read.
 bool AppInit2()
 {
     // ********************************************************* Step 1: setup
@@ -352,6 +374,14 @@ bool AppInit2()
     typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
     PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
     if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
+
+    // Initialize Windows Sockets
+    WSADATA wsadata;
+    int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
+    if (ret != NO_ERROR)
+    {
+        return InitError(strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret));
+    }
 #endif
 #ifndef WIN32
     umask(077);
@@ -374,28 +404,26 @@ bool AppInit2()
 
     // ********************************************************* Step 2: parameter interactions
 
-    nNodeLifespan = (unsigned int)(GetArg("-addrlifespan", 7));
+    nNodeLifespan = GetArgUInt("-addrlifespan", 7);
     fUseFastIndex = GetBoolArg("-fastindex", true);
     fUseMemoryLog = GetBoolArg("-memorylog", true);
 
     // Ping and address broadcast intervals
     nPingInterval = max<int64_t>(10 * 60, GetArg("-keepalive", 30 * 60));
 
-    nBroadcastInterval = max<int64_t>(6 * 60 * 60, GetArg("-addrsetlifetime", 24 * 60 * 60));
-
-    CheckpointsMode = Checkpoints::STRICT;
-    std::string strCpMode = GetArg("-cppolicy", "strict");
+    CheckpointsMode = Checkpoints::CP_STRICT;
+    auto strCpMode = GetArg("-cppolicy", "strict");
 
     if(strCpMode == "strict") {
-        CheckpointsMode = Checkpoints::STRICT;
+        CheckpointsMode = Checkpoints::CP_STRICT;
     }
 
     if(strCpMode == "advisory") {
-        CheckpointsMode = Checkpoints::ADVISORY;
+        CheckpointsMode = Checkpoints::CP_ADVISORY;
     }
 
     if(strCpMode == "permissive") {
-        CheckpointsMode = Checkpoints::PERMISSIVE;
+        CheckpointsMode = Checkpoints::CP_PERMISSIVE;
     }
 
     fTestNet = GetBoolArg("-testnet");
@@ -422,7 +450,6 @@ bool AppInit2()
 
     if (!GetBoolArg("-listen", true)) {
         // do not map ports or try to retrieve public IP when not listening (pointless)
-        SoftSetBoolArg("-upnp", false);
         SoftSetBoolArg("-discover", false);
     }
 
@@ -445,7 +472,7 @@ bool AppInit2()
     // ********************************************************* Step 3: parameter-to-internal-flags
 
     // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
-    nScriptCheckThreads = (int)(GetArg("-par", 0));
+    nScriptCheckThreads = GetArgInt("-par", 0);
     if (nScriptCheckThreads == 0)
         nScriptCheckThreads = boost::thread::hardware_concurrency();
     if (nScriptCheckThreads <= 1) 
@@ -484,7 +511,7 @@ bool AppInit2()
 
     if (mapArgs.count("-timeout"))
     {
-        int nNewTimeout = (int)(GetArg("-timeout", 5000));
+        int nNewTimeout = GetArgInt("-timeout", 5000);
         if (nNewTimeout > 0 && nNewTimeout < 600000)
             nConnectTimeout = nNewTimeout;
     }
@@ -510,7 +537,7 @@ bool AppInit2()
 
     // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
 
-    std::string strDataDir = GetDataDir().string();
+    auto strDataDir = GetDataDir().string();
     strWalletFileName = GetArg("-wallet", "wallet.dat");
 
     // strWalletFileName must be a plain filename without a directory
@@ -556,7 +583,6 @@ bool AppInit2()
         printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
     printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
     printf("Used data directory %s\n", strDataDir.c_str());
-    std::ostringstream strErrors;
 
     if (fDaemon)
         fprintf(stdout, "NovaCoin server starting\n");
@@ -567,8 +593,6 @@ bool AppInit2()
             NewThread(ThreadScriptCheck, NULL);
     }
 
-    int64_t nStart;
-
     // ********************************************************* Step 5: verify database integrity
 
     uiInterface.InitMessage(_("Verifying database integrity..."));
@@ -605,14 +629,14 @@ bool AppInit2()
 
     // ********************************************************* Step 6: network initialization
 
-    int nSocksVersion = (int)(GetArg("-socks", 5));
+    int nSocksVersion = GetArgInt("-socks", 5);
 
     if (nSocksVersion != 4 && nSocksVersion != 5)
         return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
 
     if (mapArgs.count("-onlynet")) {
         std::set<enum Network> nets;
-        BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
+        for(std::string snet :  mapMultiArgs["-onlynet"]) {
             enum Network net = ParseNetwork(snet);
             if (net == NET_UNROUTABLE)
                 return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str()));
@@ -669,13 +693,10 @@ bool AppInit2()
         fNoListen = !GetBoolArg("-listen", true);
         fDiscover = GetBoolArg("-discover", true);
         fNameLookup = GetBoolArg("-dns", true);
-#ifdef USE_UPNP
-        fUseUPnP = GetBoolArg("-upnp", USE_UPNP);
-#endif
     } else {
         // Don't listen, discover addresses or search for nodes if IPv4 and IPv6 networking is disabled.
         fNoListen = true;
-        fDiscover = fNameLookup = fUseUPnP = false;
+        fDiscover = fNameLookup = false;
         SoftSetBoolArg("-irc", false);
         SoftSetBoolArg("-dnsseed", false);
     }
@@ -683,9 +704,8 @@ bool AppInit2()
     bool fBound = false;
     if (!fNoListen)
     {
-        std::string strError;
         if (mapArgs.count("-bind")) {
-            BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
+            for(std::string strBind :  mapMultiArgs["-bind"]) {
                 CService addrBind;
                 if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
                     return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str()));
@@ -723,7 +743,7 @@ bool AppInit2()
 
     if (mapArgs.count("-externalip"))
     {
-        BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
+        for(string strAddr :  mapMultiArgs["-externalip"]) {
             CService addrLocal(strAddr, GetListenPort(), fNameLookup);
             if (!addrLocal.IsValid())
                 return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
@@ -746,7 +766,7 @@ bool AppInit2()
             InitError(_("Unable to sign checkpoint, wrong checkpointkey?\n"));
     }
 
-    BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
+    for(string strDest :  mapMultiArgs["-seednode"])
         AddOneShot(strDest);
 
     // ********************************************************* Step 7: load blockchain
@@ -770,6 +790,7 @@ bool AppInit2()
 
     printf("Loading block index...\n");
     bool fLoaded = false;
+    int64_t nStart;
     while (!fLoaded) {
         std::string strLoadError;
         uiInterface.InitMessage(_("Loading block index..."));
@@ -783,8 +804,7 @@ bool AppInit2()
                     strLoadError = _("Error loading block database");
                     break;
                 }
-            } catch(std::exception &e) {
-                (void)e;
+            } catch(const std::exception&) {
                 strLoadError = _("Error opening block database");
                 break;
             }
@@ -793,6 +813,7 @@ bool AppInit2()
         } while(false);
 
         if (!fLoaded) {
+            DropBlockIndex();
             // TODO: suggest reindex here
             return InitError(strLoadError);
         }
@@ -816,14 +837,14 @@ bool AppInit2()
 
     if (mapArgs.count("-printblock"))
     {
-        string strMatch = mapArgs["-printblock"];
+        auto strMatch = mapArgs["-printblock"];
         int nFound = 0;
-        for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
+        for (auto mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
         {
-            uint256 hash = (*mi).first;
-            if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
+            auto hash = (*mi).first;
+            if (strMatch.compare(hash.ToString()) == 0)
             {
-                CBlockIndex* pindex = (*mi).second;
+                auto pindex = (*mi).second;
                 CBlock block;
                 block.ReadFromDisk(pindex);
                 block.BuildMerkleTree();
@@ -855,6 +876,7 @@ bool AppInit2()
     uiInterface.InitMessage(_("Loading wallet..."));
     printf("Loading wallet...\n");
     nStart = GetTimeMillis();
+    std::ostringstream strErrors;
     bool fFirstRun = true;
     pwalletMain = new CWallet(strWalletFileName);
     DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
@@ -882,7 +904,7 @@ bool AppInit2()
 
     if (GetBoolArg("-upgradewallet", fFirstRun))
     {
-        int nMaxVersion = (int)(GetArg("-upgradewallet", 0));
+        int nMaxVersion = GetArgInt("-upgradewallet", 0);
         if (nMaxVersion == 0) // the -upgradewallet without argument case
         {
             printf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
@@ -907,6 +929,13 @@ bool AppInit2()
         pwalletMain->SetDefaultKey(newDefaultKey);
         if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), ""))
             strErrors << _("Cannot write default address") << "\n";
+
+        auto keyView = pwalletMain->GenerateNewMalleableKey();
+        CMalleableKey mKey;
+        if (!pwalletMain->GetMalleableKey(keyView, mKey))
+            strErrors << _("Unable to generate new malleable key");
+        if (!pwalletMain->SetAddressBookName(CBitcoinAddress(keyView.GetMalleablePubKey()), ""))
+            strErrors << _("Cannot write default address") << "\n";
     }
 
     printf("%s", strErrors.str().c_str());
@@ -939,11 +968,11 @@ bool AppInit2()
     {
         uiInterface.InitMessage(_("Importing blockchain data file."));
 
-        BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
+        for(string strFile :  mapMultiArgs["-loadblock"])
         {
             FILE *file = fopen(strFile.c_str(), "rb");
             if (file)
-                LoadExternalBlockFile(file);
+                LoadExternalBlockFile(file, uiInterface);
         }
         StartShutdown();
     }
@@ -955,7 +984,7 @@ bool AppInit2()
         FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
         if (file) {
             filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
-            LoadExternalBlockFile(file);
+            LoadExternalBlockFile(file, uiInterface);
             RenameOver(pathBootstrap, pathBootstrapOld);
         }
     }
@@ -995,7 +1024,11 @@ bool AppInit2()
     if (fServer)
         NewThread(ThreadRPCServer, NULL);
 
-    // ********************************************************* Step 12: finished
+    // ********************************************************* Step 13: IP collection thread
+    strCollectorCommand = GetArg("-peercollector", "");
+    if (!fTestNet && strCollectorCommand != "")
+        NewThread(ThreadIPCollector, NULL);
+    // ********************************************************* Step 14: finished
 
     uiInterface.InitMessage(_("Done loading"));
     printf("Done loading\n");
@@ -1009,7 +1042,7 @@ bool AppInit2()
 #if !defined(QT_GUI)
     // Loop until process is exit()ed from shutdown() function,
     // called from ThreadRPCServer thread when a "stop" command is received.
-    while (1)
+    for ( ; ; )
         Sleep(5000);
 #endif