aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp165
1 files changed, 130 insertions, 35 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 4d5720306d..7f311fa881 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -2,6 +2,7 @@
// 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.
+
#include "txdb.h"
#include "walletdb.h"
#include "bitcoinrpc.h"
@@ -9,6 +10,7 @@
#include "init.h"
#include "util.h"
#include "ui_interface.h"
+
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp>
@@ -26,6 +28,13 @@ using namespace boost;
CWallet* pwalletMain;
CClientUIInterface uiInterface;
+// Used to pass flags to the Bind() function
+enum BindFlags {
+ BF_NONE = 0,
+ BF_EXPLICIT = (1U << 0),
+ BF_REPORT_ERROR = (1U << 1)
+};
+
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
@@ -78,8 +87,10 @@ void Shutdown(void* parg)
StopNode();
{
LOCK(cs_main);
- pcoinsTip->Flush();
- pblocktree->Flush();
+ if (pblocktree)
+ pblocktree->Flush();
+ if (pcoinsTip)
+ pcoinsTip->Flush();
delete pcoinsTip;
delete pcoinsdbview;
delete pblocktree;
@@ -200,23 +211,22 @@ int main(int argc, char* argv[])
bool static InitError(const std::string &str)
{
- uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::MODAL);
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
return false;
}
bool static InitWarning(const std::string &str)
{
- uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
return true;
}
-
-bool static Bind(const CService &addr, bool fError = true) {
- if (IsLimited(addr))
+bool static Bind(const CService &addr, unsigned int flags) {
+ if (!(flags & BF_EXPLICIT) && IsLimited(addr))
return false;
std::string strError;
if (!BindListenPort(addr, strError)) {
- if (fError)
+ if (flags & BF_REPORT_ERROR)
return InitError(strError);
return false;
}
@@ -234,7 +244,6 @@ std::string HelpMessage()
" -gen=0 " + _("Don't generate coins") + "\n" +
" -datadir=<dir> " + _("Specify data directory") + "\n" +
" -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" +
- " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
" -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" +
" -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
" -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
@@ -249,8 +258,9 @@ std::string HelpMessage()
" -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n" +
" -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" +
" -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" +
+ " -checkpoints " + _("Lock in block chain with compiled-in checkpoints (default: 1)") + "\n" +
" -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" +
- " -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" +
+ " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n" +
" -dnsseed " + _("Find peers using DNS lookup (default: 1 unless -connect)") + "\n" +
" -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
" -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
@@ -263,7 +273,6 @@ std::string HelpMessage()
" -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" +
" -paytxfee=<amt> " + _("Fee per KB to add to transactions you send") + "\n" +
#ifdef QT_GUI
" -server " + _("Accept command line and JSON-RPC commands") + "\n" +
@@ -293,6 +302,7 @@ std::string HelpMessage()
" -checkblocks=<n> " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
" -checklevel=<n> " + _("How thorough the block verification is (0-6, default: 1)") + "\n" +
" -loadblock=<file> " + _("Imports blocks from external blk000?.dat file") + "\n" +
+ " -reindex " + _("Rebuild blockchain index from current blk000??.dat files") + "\n" +
"\n" + _("Block creation options:") + "\n" +
" -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n" +
@@ -308,6 +318,79 @@ std::string HelpMessage()
return strUsage;
}
+struct CImportingNow
+{
+ CImportingNow() {
+ assert(fImporting == false);
+ fImporting = true;
+ }
+
+ ~CImportingNow() {
+ assert(fImporting == true);
+ fImporting = false;
+ }
+};
+
+struct CImportData {
+ std::vector<boost::filesystem::path> vFiles;
+};
+
+void ThreadImport(void *data) {
+ CImportData *import = reinterpret_cast<CImportData*>(data);
+
+ RenameThread("bitcoin-loadblk");
+
+ vnThreadsRunning[THREAD_IMPORT]++;
+
+ // -reindex
+ if (fReindex) {
+ CImportingNow imp;
+ int nFile = 0;
+ while (!fRequestShutdown) {
+ CDiskBlockPos pos(nFile, 0);
+ FILE *file = OpenBlockFile(pos, true);
+ if (!file)
+ break;
+ printf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
+ LoadExternalBlockFile(file, &pos);
+ nFile++;
+ }
+ if (!fRequestShutdown) {
+ pblocktree->WriteReindexing(false);
+ fReindex = false;
+ printf("Reindexing finished\n");
+ }
+ }
+
+ // hardcoded $DATADIR/bootstrap.dat
+ filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
+ if (filesystem::exists(pathBootstrap) && !fRequestShutdown) {
+ FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
+ if (file) {
+ CImportingNow imp;
+ filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
+ printf("Importing bootstrap.dat...\n");
+ LoadExternalBlockFile(file);
+ RenameOver(pathBootstrap, pathBootstrapOld);
+ }
+ }
+
+ // -loadblock=
+ BOOST_FOREACH(boost::filesystem::path &path, import->vFiles) {
+ if (fRequestShutdown)
+ break;
+ FILE *file = fopen(path.string().c_str(), "rb");
+ if (file) {
+ CImportingNow imp;
+ printf("Importing %s...\n", path.string().c_str());
+ LoadExternalBlockFile(file);
+ }
+ }
+
+ delete import;
+
+ vnThreadsRunning[THREAD_IMPORT]--;
+}
/** Initialize bitcoin.
* @pre Parameters should be parsed and config file should be read.
@@ -399,6 +482,7 @@ bool AppInit2()
// ********************************************************* Step 3: parameter-to-internal-flags
fDebug = GetBoolArg("-debug");
+ fBenchmark = GetBoolArg("-benchmark");
// -debug implies fDebug*
if (fDebug)
@@ -406,8 +490,6 @@ bool AppInit2()
else
fDebugNet = GetBoolArg("-debugnet");
- bitdb.SetDetach(GetBoolArg("-detachdb", false));
-
#if !defined(WIN32) && !defined(QT_GUI)
fDaemon = GetBoolArg("-daemon");
#else
@@ -459,7 +541,7 @@ bool AppInit2()
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."), strDataDir.c_str()));
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), strDataDir.c_str()));
#if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon)
@@ -527,7 +609,7 @@ bool AppInit2()
" Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
" your balance or transactions are incorrect you should"
" restore from a backup."), strDataDir.c_str());
- uiInterface.ThreadSafeMessageBox(msg, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
+ InitWarning(msg);
}
if (r == CDBEnv::RECOVER_FAIL)
return InitError(_("wallet.dat corrupt, salvage failed"));
@@ -602,32 +684,28 @@ bool AppInit2()
#endif
bool fBound = false;
- if (!fNoListen)
- {
- std::string strError;
+ if (!fNoListen) {
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);
+ fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
}
- } else {
+ }
+ else {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
#ifdef USE_IPV6
- if (!IsLimited(NET_IPV6))
- fBound |= Bind(CService(in6addr_any, GetListenPort()), false);
+ fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
#endif
- if (!IsLimited(NET_IPV4))
- fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound);
+ fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
}
if (!fBound)
return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
}
- if (mapArgs.count("-externalip"))
- {
+ if (mapArgs.count("-externalip")) {
BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
if (!addrLocal.IsValid())
@@ -639,7 +717,9 @@ bool AppInit2()
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
AddOneShot(strDest);
- // ********************************************************* Step 7: load blockchain
+ // ********************************************************* Step 7: load block chain
+
+ fReindex = GetBoolArg("-reindex");
if (!bitdb.Open(GetDataDir()))
{
@@ -649,13 +729,28 @@ bool AppInit2()
return InitError(msg);
}
+ // cache size calculations
+ size_t nTotalCache = GetArg("-dbcache", 25) << 20;
+ if (nTotalCache < (1 << 22))
+ nTotalCache = (1 << 22); // total cache cannot be less than 4 MiB
+ size_t nBlockTreeDBCache = nTotalCache / 8;
+ if (nBlockTreeDBCache > (1 << 21))
+ nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
+ nTotalCache -= nBlockTreeDBCache;
+ size_t nCoinDBCache = nTotalCache / 2; // use half of the remaining cache for coindb cache
+ nTotalCache -= nCoinDBCache;
+ nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes
+
uiInterface.InitMessage(_("Loading block index..."));
printf("Loading block index...\n");
nStart = GetTimeMillis();
- pblocktree = new CBlockTreeDB();
- pcoinsdbview = new CCoinsViewDB();
+ pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
+ pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
+ if (fReindex)
+ pblocktree->WriteReindexing(true);
+
if (!LoadBlockIndex())
return InitError(_("Error loading blkindex.dat"));
@@ -714,7 +809,7 @@ bool AppInit2()
{
string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
" or address book entries might be missing or incorrect."));
- uiInterface.ThreadSafeMessageBox(msg, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
+ InitWarning(msg);
}
else if (nLoadWalletRet == DB_TOO_NEW)
strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n";
@@ -772,7 +867,7 @@ bool AppInit2()
if (walletdb.ReadBestBlock(locator))
pindexRescan = locator.GetBlockIndex();
}
- if (pindexBest != pindexRescan)
+ if (pindexBest && pindexBest != pindexRescan)
{
uiInterface.InitMessage(_("Rescanning..."));
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
@@ -788,13 +883,13 @@ bool AppInit2()
if (!ConnectBestBlock())
strErrors << "Failed to connect best block";
- std::vector<boost::filesystem::path> *vPath = new std::vector<boost::filesystem::path>();
+ CImportData *pimport = new CImportData();
if (mapArgs.count("-loadblock"))
{
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
- vPath->push_back(strFile);
+ pimport->vFiles.push_back(strFile);
}
- NewThread(ThreadImport, vPath);
+ NewThread(ThreadImport, pimport);
// ********************************************************* Step 10: load peers
@@ -820,7 +915,7 @@ bool AppInit2()
//// debug print
printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size());
- printf("nBestHeight = %d\n", nBestHeight);
+ printf("nBestHeight = %d\n", nBestHeight);
printf("setKeyPool.size() = %"PRIszu"\n", pwalletMain->setKeyPool.size());
printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size());