aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp453
1 files changed, 240 insertions, 213 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 809c07f375..c01dc27086 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "db.h"
#include "walletdb.h"
#include "bitcoinrpc.h"
@@ -13,6 +13,7 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/algorithm/string/predicate.hpp>
#ifndef WIN32
#include <signal.h>
@@ -22,6 +23,7 @@ using namespace std;
using namespace boost;
CWallet* pwalletMain;
+CClientUIInterface uiInterface;
//////////////////////////////////////////////////////////////////////////////
//
@@ -80,6 +82,10 @@ void HandleSIGTERM(int)
fRequestShutdown = true;
}
+void HandleSIGHUP(int)
+{
+ fReopenDebugLog = true;
+}
@@ -90,17 +96,6 @@ void HandleSIGTERM(int)
// Start
//
#if !defined(QT_GUI)
-int main(int argc, char* argv[])
-{
- bool fRet = false;
- fRet = AppInit(argc, argv);
-
- if (fRet && fDaemon)
- return 0;
-
- return 1;
-}
-
bool AppInit(int argc, char* argv[])
{
bool fRet = false;
@@ -136,7 +131,7 @@ bool AppInit(int argc, char* argv[])
// Command-line RPC
for (int i = 1; i < argc; i++)
- if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0))
+ if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:"))
fCommandLine = true;
if (fCommandLine)
@@ -156,17 +151,33 @@ bool AppInit(int argc, char* argv[])
Shutdown(NULL);
return fRet;
}
+
+extern void noui_connect();
+int main(int argc, char* argv[])
+{
+ bool fRet = false;
+
+ // Connect bitcoind signal handlers
+ noui_connect();
+
+ fRet = AppInit(argc, argv);
+
+ if (fRet && fDaemon)
+ return 0;
+
+ return 1;
+}
#endif
bool static InitError(const std::string &str)
{
- ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxMODAL);
+ uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::MODAL);
return false;
}
bool static InitWarning(const std::string &str)
{
- ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL);
+ uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
return true;
}
@@ -264,6 +275,7 @@ std::string HelpMessage()
*/
bool AppInit2()
{
+ // ********************************************************* Step 1: setup
#ifdef _MSC_VER
// Turn off microsoft heap dump noise
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
@@ -284,15 +296,44 @@ bool AppInit2()
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
- sigaction(SIGHUP, &sa, NULL);
+
+ // Reopen debug.log on SIGHUP
+ struct sigaction sa_hup;
+ sa_hup.sa_handler = HandleSIGHUP;
+ sigemptyset(&sa_hup.sa_mask);
+ sa_hup.sa_flags = 0;
+ sigaction(SIGHUP, &sa_hup, NULL);
#endif
+ // ********************************************************* Step 2: parameter interactions
+
fTestNet = GetBoolArg("-testnet");
if (fTestNet)
{
SoftSetBoolArg("-irc", true);
}
+ if (mapArgs.count("-connect"))
+ SoftSetBoolArg("-dnsseed", false);
+
+ // even in Tor mode, if -bind is specified, you really want -listen
+ if (mapArgs.count("-bind"))
+ SoftSetBoolArg("-listen", true);
+
+ bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
+ if (fTor)
+ {
+ // Use SoftSetBoolArg here so user can override any of these if they wish.
+ // Note: the GetBoolArg() calls for all of these must happen later.
+ SoftSetBoolArg("-listen", false);
+ SoftSetBoolArg("-irc", false);
+ SoftSetBoolArg("-proxydns", true);
+ SoftSetBoolArg("-upnp", false);
+ SoftSetBoolArg("-discover", false);
+ }
+
+ // ********************************************************* Step 3: parameter-to-internal-flags
+
fDebug = GetBoolArg("-debug");
bitdb.SetDetach(GetBoolArg("-detachdb", false));
@@ -315,6 +356,38 @@ bool AppInit2()
fPrintToDebugger = GetBoolArg("-printtodebugger");
fLogTimestamps = GetBoolArg("-logtimestamps");
+ if (mapArgs.count("-timeout"))
+ {
+ int nNewTimeout = GetArg("-timeout", 5000);
+ if (nNewTimeout > 0 && nNewTimeout < 600000)
+ nConnectTimeout = nNewTimeout;
+ }
+
+ // Continue to put "/P2SH/" in the coinbase to monitor
+ // BIP16 support.
+ // This can be removed eventually...
+ const char* pszP2SH = "/P2SH/";
+ COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
+
+
+ if (mapArgs.count("-paytxfee"))
+ {
+ if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
+ return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str()));
+ if (nTransactionFee > 0.25 * COIN)
+ InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."));
+ }
+
+ // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
+
+ // Make sure only a single Bitcoin process is using the data directory.
+ boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
+ FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
+ if (file) fclose(file);
+ static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
+ if (!lock.try_lock())
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()));
+
#if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon)
{
@@ -342,45 +415,106 @@ bool AppInit2()
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("Default data directory %s\n", GetDefaultDataDir().string().c_str());
+ std::ostringstream strErrors;
- if (GetBoolArg("-loadblockindextest"))
+ if (fDaemon)
+ fprintf(stdout, "Bitcoin server starting\n");
+
+ int64 nStart;
+
+ // ********************************************************* Step 5: network initialization
+
+ if (mapArgs.count("-proxy"))
{
- CTxDB txdb("r");
- txdb.LoadBlockIndex();
- PrintBlockTree();
- return false;
+ fUseProxy = true;
+ addrProxy = CService(mapArgs["-proxy"], 9050);
+ if (!addrProxy.IsValid())
+ return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
}
- // Make sure only a single Bitcoin process is using the data directory.
- boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
- FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
- if (file) fclose(file);
- static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
- if (!lock.try_lock())
- return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()));
+ if (mapArgs.count("-noproxy"))
+ {
+ BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
+ enum Network net = ParseNetwork(snet);
+ if (net == NET_UNROUTABLE)
+ return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
+ SetNoProxy(net);
+ }
+ }
- std::ostringstream strErrors;
- //
- // Load data files
- //
- if (fDaemon)
- fprintf(stdout, "Bitcoin server starting\n");
- int64 nStart;
+ fNameLookup = GetBoolArg("-dns");
+ fProxyNameLookup = GetBoolArg("-proxydns");
+ if (fProxyNameLookup)
+ fNameLookup = true;
+ fNoListen = !GetBoolArg("-listen", true);
+ nSocksVersion = GetArg("-socks", 5);
+ if (nSocksVersion != 4 && nSocksVersion != 5)
+ return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
- InitMessage(_("Loading addresses..."));
- printf("Loading addresses...\n");
- nStart = GetTimeMillis();
+ if (mapArgs.count("-onlynet")) {
+ std::set<enum Network> nets;
+ BOOST_FOREACH(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()));
+ nets.insert(net);
+ }
+ for (int n = 0; n < NET_MAX; n++) {
+ enum Network net = (enum Network)n;
+ if (!nets.count(net))
+ SetLimited(net);
+ }
+ }
+
+ BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
+ AddOneShot(strDest);
+ bool fBound = false;
+ if (!fNoListen)
{
- CAddrDB adb;
- if (!adb.Read(addrman))
- printf("Invalid or missing peers.dat; recreating\n");
+ std::string strError;
+ if (mapArgs.count("-bind")) {
+ BOOST_FOREACH(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()));
+ fBound |= Bind(addrBind);
+ }
+ } else {
+ struct in_addr inaddr_any;
+ inaddr_any.s_addr = INADDR_ANY;
+ if (!IsLimited(NET_IPV4))
+ fBound |= Bind(CService(inaddr_any, GetListenPort()));
+#ifdef USE_IPV6
+ if (!IsLimited(NET_IPV6))
+ fBound |= Bind(CService(in6addr_any, GetListenPort()));
+#endif
+ }
+ if (!fBound)
+ return InitError(_("Not listening on any port"));
}
- printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
- addrman.size(), GetTimeMillis() - nStart);
+ if (mapArgs.count("-externalip"))
+ {
+ BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
+ CService addrLocal(strAddr, GetListenPort(), fNameLookup);
+ if (!addrLocal.IsValid())
+ return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
+ AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
+ }
+ }
+
+ // ********************************************************* Step 6: load blockchain
+
+ if (GetBoolArg("-loadblockindextest"))
+ {
+ CTxDB txdb("r");
+ txdb.LoadBlockIndex();
+ PrintBlockTree();
+ return false;
+ }
- InitMessage(_("Loading block index..."));
+ uiInterface.InitMessage(_("Loading block index..."));
printf("Loading block index...\n");
nStart = GetTimeMillis();
if (!LoadBlockIndex())
@@ -396,17 +530,38 @@ bool AppInit2()
}
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
- if (mapArgs.count("-loadblock"))
+ if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
{
- BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
+ PrintBlockTree();
+ return false;
+ }
+
+ if (mapArgs.count("-printblock"))
+ {
+ string strMatch = mapArgs["-printblock"];
+ int nFound = 0;
+ for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
{
- FILE *file = fopen(strFile.c_str(), "rb");
- if (file)
- LoadExternalBlockFile(file);
+ uint256 hash = (*mi).first;
+ if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
+ {
+ CBlockIndex* pindex = (*mi).second;
+ CBlock block;
+ block.ReadFromDisk(pindex);
+ block.BuildMerkleTree();
+ block.print();
+ printf("\n");
+ nFound++;
+ }
}
+ if (nFound == 0)
+ printf("No blocks matching %s were found\n", strMatch.c_str());
+ return false;
}
- InitMessage(_("Loading wallet..."));
+ // ********************************************************* Step 7: load wallet
+
+ uiInterface.InitMessage(_("Loading wallet..."));
printf("Loading wallet...\n");
nStart = GetTimeMillis();
bool fFirstRun;
@@ -474,199 +629,71 @@ bool AppInit2()
}
if (pindexBest != pindexRescan)
{
- InitMessage(_("Rescanning..."));
+ uiInterface.InitMessage(_("Rescanning..."));
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
nStart = GetTimeMillis();
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
}
- InitMessage(_("Done loading"));
- printf("Done loading\n");
-
- //// debug print
- printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
- printf("nBestHeight = %d\n", nBestHeight);
- printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
- printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
- printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
-
- if (!strErrors.str().empty())
- return InitError(strErrors.str());
-
- // Add wallet transactions that aren't already in a block to mapTransactions
- pwalletMain->ReacceptWalletTransactions();
-
- // Note: Bitcoin-Qt stores several settings in the wallet, so we want
- // to load the wallet BEFORE parsing command-line arguments, so
- // the command-line/bitcoin.conf settings override GUI setting.
-
- //
- // Parameters
- //
- if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
- {
- PrintBlockTree();
- return false;
- }
-
- if (mapArgs.count("-timeout"))
- {
- int nNewTimeout = GetArg("-timeout", 5000);
- if (nNewTimeout > 0 && nNewTimeout < 600000)
- nConnectTimeout = nNewTimeout;
- }
+ // ********************************************************* Step 8: import blocks
- if (mapArgs.count("-printblock"))
+ if (mapArgs.count("-loadblock"))
{
- string strMatch = mapArgs["-printblock"];
- int nFound = 0;
- for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
+ BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
{
- uint256 hash = (*mi).first;
- if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
- {
- CBlockIndex* pindex = (*mi).second;
- CBlock block;
- block.ReadFromDisk(pindex);
- block.BuildMerkleTree();
- block.print();
- printf("\n");
- nFound++;
- }
- }
- if (nFound == 0)
- printf("No blocks matching %s were found\n", strMatch.c_str());
- return false;
- }
-
- if (mapArgs.count("-proxy"))
- {
- fUseProxy = true;
- addrProxy = CService(mapArgs["-proxy"], 9050);
- if (!addrProxy.IsValid())
- return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
- }
-
- if (mapArgs.count("-noproxy"))
- {
- BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
- enum Network net = ParseNetwork(snet);
- if (net == NET_UNROUTABLE)
- return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
- SetNoProxy(net);
- }
- }
-
- if (mapArgs.count("-connect"))
- SoftSetBoolArg("-dnsseed", false);
-
- // even in Tor mode, if -bind is specified, you really want -listen
- if (mapArgs.count("-bind"))
- SoftSetBoolArg("-listen", true);
-
- bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
- if (fTor)
- {
- // Use SoftSetBoolArg here so user can override any of these if they wish.
- // Note: the GetBoolArg() calls for all of these must happen later.
- SoftSetBoolArg("-listen", false);
- SoftSetBoolArg("-irc", false);
- SoftSetBoolArg("-proxydns", true);
- SoftSetBoolArg("-upnp", false);
- SoftSetBoolArg("-discover", false);
- }
-
- if (mapArgs.count("-onlynet")) {
- std::set<enum Network> nets;
- BOOST_FOREACH(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()));
- nets.insert(net);
- }
- for (int n = 0; n < NET_MAX; n++) {
- enum Network net = (enum Network)n;
- if (!nets.count(net))
- SetLimited(net);
+ FILE *file = fopen(strFile.c_str(), "rb");
+ if (file)
+ LoadExternalBlockFile(file);
}
}
- fNameLookup = GetBoolArg("-dns");
- fProxyNameLookup = GetBoolArg("-proxydns");
- if (fProxyNameLookup)
- fNameLookup = true;
- fNoListen = !GetBoolArg("-listen", true);
- nSocksVersion = GetArg("-socks", 5);
- if (nSocksVersion != 4 && nSocksVersion != 5)
- return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
+ // ********************************************************* Step 9: load peers
- BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
- AddOneShot(strDest);
-
- // Continue to put "/P2SH/" in the coinbase to monitor
- // BIP16 support.
- // This can be removed eventually...
- const char* pszP2SH = "/P2SH/";
- COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
+ uiInterface.InitMessage(_("Loading addresses..."));
+ printf("Loading addresses...\n");
+ nStart = GetTimeMillis();
- bool fBound = false;
- if (!fNoListen)
{
- std::string strError;
- if (mapArgs.count("-bind")) {
- BOOST_FOREACH(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()));
- fBound |= Bind(addrBind);
- }
- } else {
- struct in_addr inaddr_any;
- inaddr_any.s_addr = INADDR_ANY;
- if (!IsLimited(NET_IPV4))
- fBound |= Bind(CService(inaddr_any, GetListenPort()));
-#ifdef USE_IPV6
- if (!IsLimited(NET_IPV6))
- fBound |= Bind(CService(in6addr_any, GetListenPort()));
-#endif
- }
- if (!fBound)
- return InitError(_("Not listening on any port"));
+ CAddrDB adb;
+ if (!adb.Read(addrman))
+ printf("Invalid or missing peers.dat; recreating\n");
}
- if (mapArgs.count("-externalip"))
- {
- BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
- CService addrLocal(strAddr, GetListenPort(), fNameLookup);
- if (!addrLocal.IsValid())
- return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
- AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
- }
- }
+ printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
+ addrman.size(), GetTimeMillis() - nStart);
- if (mapArgs.count("-paytxfee"))
- {
- if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
- return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str()));
- if (nTransactionFee > 0.25 * COIN)
- InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."));
- }
+ // ********************************************************* Step 10: start node
- //
- // Start the node
- //
if (!CheckDiskSpace())
return false;
RandAddSeedPerfmon();
+ //// debug print
+ printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
+ printf("nBestHeight = %d\n", nBestHeight);
+ printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
+ printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
+ printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
+
if (!CreateThread(StartNode, NULL))
InitError(_("Error: could not start node"));
if (fServer)
CreateThread(ThreadRPCServer, NULL);
+ // ********************************************************* Step 11: finished
+
+ uiInterface.InitMessage(_("Done loading"));
+ printf("Done loading\n");
+
+ if (!strErrors.str().empty())
+ return InitError(strErrors.str());
+
+ // Add wallet transactions that aren't already in a block to mapTransactions
+ pwalletMain->ReacceptWalletTransactions();
+
#if !defined(QT_GUI)
// Loop until process is exit()ed from shutdown() function,
// called from ThreadRPCServer thread when a "stop" command is received.