|
|
|
@ -275,6 +275,7 @@ std::string HelpMessage()
@@ -275,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); |
|
|
|
@ -304,12 +305,35 @@ bool AppInit2()
@@ -304,12 +305,35 @@ bool AppInit2()
|
|
|
|
|
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"); |
|
|
|
|
fDetachDB = GetBoolArg("-detachdb", false); |
|
|
|
|
|
|
|
|
@ -332,6 +356,38 @@ bool AppInit2()
@@ -332,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) |
|
|
|
|
{ |
|
|
|
@ -359,43 +415,104 @@ bool AppInit2()
@@ -359,43 +415,104 @@ 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)); |
|
|
|
|
|
|
|
|
|
uiInterface.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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uiInterface.InitMessage(_("Loading block index...")); |
|
|
|
|
printf("Loading block index...\n"); |
|
|
|
@ -413,15 +530,36 @@ bool AppInit2()
@@ -413,15 +530,36 @@ 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")) |
|
|
|
|
{ |
|
|
|
|
FILE *file = fopen(strFile.c_str(), "rb"); |
|
|
|
|
if (file) |
|
|
|
|
LoadExternalBlockFile(file); |
|
|
|
|
string strMatch = mapArgs["-printblock"]; |
|
|
|
|
int nFound = 0; |
|
|
|
|
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) |
|
|
|
|
{ |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ********************************************************* Step 7: load wallet
|
|
|
|
|
|
|
|
|
|
uiInterface.InitMessage(_("Loading wallet...")); |
|
|
|
|
printf("Loading wallet...\n"); |
|
|
|
@ -498,192 +636,64 @@ bool AppInit2()
@@ -498,192 +636,64 @@ bool AppInit2()
|
|
|
|
|
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uiInterface.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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mapArgs.count("-printblock")) |
|
|
|
|
{ |
|
|
|
|
string strMatch = mapArgs["-printblock"]; |
|
|
|
|
int nFound = 0; |
|
|
|
|
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) |
|
|
|
|
{ |
|
|
|
|
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())); |
|
|
|
|
} |
|
|
|
|
// ********************************************************* Step 8: import blocks
|
|
|
|
|
|
|
|
|
|
if (mapArgs.count("-noproxy")) |
|
|
|
|
if (mapArgs.count("-loadblock")) |
|
|
|
|
{ |
|
|
|
|
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) |
|
|
|
|
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) |
|
|
|
|
{ |
|
|
|
|
// 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)); |
|
|
|
|
|
|
|
|
|
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) |
|
|
|
|
AddOneShot(strDest); |
|
|
|
|
// ********************************************************* Step 9: load peers
|
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|