2011-05-14 11:10:21 -07:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2014-12-16 17:47:57 -08:00
// Copyright (c) 2009-2014 The Bitcoin Core developers
2014-11-30 17:39:44 -08:00
// Distributed under the MIT software license, see the accompanying
2019-07-18 07:16:09 -07:00
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
2012-11-04 23:04:21 -08:00
2013-05-27 16:55:01 -07:00
# if defined(HAVE_CONFIG_H)
2014-06-23 11:04:24 -07:00
# include "config/bitcoin-config.h"
2013-05-27 16:55:01 -07:00
# endif
2013-01-07 08:07:51 -08:00
# include "init.h"
2013-04-12 22:13:08 -07:00
# include "addrman.h"
2014-10-22 17:05:11 -07:00
# include "amount.h"
2013-04-12 22:13:08 -07:00
# include "checkpoints.h"
2014-09-14 03:43:56 -07:00
# include "compat/sanity.h"
2018-01-31 12:11:18 -08:00
# include "consensus/upgrades.h"
2015-01-24 06:57:12 -08:00
# include "consensus/validation.h"
2020-01-27 06:59:24 -08:00
# include "experimental_features.h"
2017-03-01 07:54:22 -08:00
# include "fs.h"
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
# include "httpserver.h"
# include "httprpc.h"
2014-06-02 16:21:03 -07:00
# include "key.h"
2020-10-27 05:11:33 -07:00
# if defined(ENABLE_MINING) || defined(ENABLE_WALLET)
2018-04-25 04:58:22 -07:00
# include "key_io.h"
# endif
2013-12-12 23:50:07 -08:00
# include "main.h"
2019-10-09 14:22:49 -07:00
# include "mempool_limit.h"
2016-09-03 09:39:45 -07:00
# include "metrics.h"
2013-07-31 06:43:35 -07:00
# include "miner.h"
2013-04-12 22:13:08 -07:00
# include "net.h"
2015-06-23 22:25:30 -07:00
# include "policy/policy.h"
2016-01-14 16:55:17 -08:00
# include "rpc/server.h"
2016-03-29 10:43:02 -07:00
# include "rpc/register.h"
2014-10-10 16:55:14 -07:00
# include "script/standard.h"
2015-10-30 15:14:38 -07:00
# include "script/sigcache.h"
2015-04-03 08:50:06 -07:00
# include "scheduler.h"
2013-04-12 22:13:08 -07:00
# include "txdb.h"
2015-08-25 11:12:08 -07:00
# include "torcontrol.h"
2012-04-15 13:10:54 -07:00
# include "ui_interface.h"
2013-04-12 22:13:08 -07:00
# include "util.h"
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
2014-08-21 07:11:09 -07:00
# include "utilmoneystr.h"
2015-03-24 14:14:44 -07:00
# include "validationinterface.h"
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2015-02-03 12:09:47 -08:00
# include "wallet/wallet.h"
# include "wallet/walletdb.h"
2013-11-29 07:04:29 -08:00
# endif
2016-11-29 22:07:42 -08:00
# include "warnings.h"
2013-04-12 22:13:08 -07:00
# include <stdint.h>
2014-05-11 06:29:16 -07:00
# include <stdio.h>
2011-05-14 11:10:21 -07:00
2012-04-15 13:10:54 -07:00
# ifndef WIN32
# include <signal.h>
2012-03-18 15:14:03 -07:00
# endif
2011-10-07 07:46:56 -07:00
2018-01-31 12:11:18 -08:00
# include <boost/algorithm/string/classification.hpp>
2013-04-12 22:13:08 -07:00
# include <boost/algorithm/string/predicate.hpp>
2014-08-29 13:52:41 -07:00
# include <boost/algorithm/string/replace.hpp>
2018-01-31 12:11:18 -08:00
# include <boost/algorithm/string/split.hpp>
2020-10-10 13:41:46 -07:00
# include <boost/bind/bind.hpp>
2013-04-12 22:13:08 -07:00
# include <boost/interprocess/sync/file_lock.hpp>
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
2014-08-21 07:11:09 -07:00
# include <boost/thread.hpp>
2020-12-17 03:31:40 -08:00
# include <sodium.h>
2013-04-12 22:13:08 -07:00
2014-11-18 09:06:32 -08:00
# if ENABLE_ZMQ
# include "zmq/zmqnotificationinterface.h"
# endif
2020-10-16 16:54:04 -07:00
# include <rust/metrics.h>
2018-04-17 13:44:53 -07:00
# include "librustzcash.h"
2020-10-10 13:41:46 -07:00
using namespace boost : : placeholders ;
2011-05-14 11:10:21 -07:00
2016-07-15 19:57:55 -07:00
extern void ThreadSendAlert ( ) ;
2020-07-10 05:51:40 -07:00
TracingHandle * pTracingHandle = nullptr ;
2014-09-18 05:08:43 -07:00
bool fFeeEstimatesInitialized = false ;
2015-06-27 12:21:41 -07:00
static const bool DEFAULT_PROXYRANDOMIZE = true ;
static const bool DEFAULT_REST_ENABLE = false ;
2015-11-09 10:16:38 -08:00
static const bool DEFAULT_DISABLE_SAFEMODE = false ;
2015-06-27 12:21:41 -07:00
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false ;
2011-06-26 10:23:24 -07:00
2016-02-10 22:35:25 -08:00
2014-11-18 09:06:32 -08:00
# if ENABLE_ZMQ
static CZMQNotificationInterface * pzmqNotificationInterface = NULL ;
# endif
2013-04-25 15:46:47 -07:00
# ifdef WIN32
2016-11-03 06:04:12 -07:00
// Win32 LevelDB doesn't use file descriptors, and the ones used for
2015-04-28 07:48:28 -07:00
// accessing block files don't count towards the fd_set size limit
2013-04-25 15:46:47 -07:00
// anyway.
# define MIN_CORE_FILEDESCRIPTORS 0
# else
# define MIN_CORE_FILEDESCRIPTORS 150
# endif
2014-11-30 17:39:44 -08:00
/** Used to pass flags to the Bind() function */
2012-09-03 06:54:47 -07:00
enum BindFlags {
2012-11-14 07:07:40 -08:00
BF_NONE = 0 ,
BF_EXPLICIT = ( 1U < < 0 ) ,
2014-06-21 04:34:36 -07:00
BF_REPORT_ERROR = ( 1U < < 1 ) ,
BF_WHITELIST = ( 1U < < 2 ) ,
2012-09-03 06:54:47 -07:00
} ;
2014-03-17 05:19:54 -07:00
static const char * FEE_ESTIMATES_FILENAME = " fee_estimates.dat " ;
2015-04-16 07:20:01 -07:00
CClientUIInterface uiInterface ; // Declared but not defined in ui_interface.h
2013-01-07 07:35:31 -08:00
2011-05-14 11:10:21 -07:00
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
//
2013-03-09 09:02:57 -08:00
//
// Thread management and startup/shutdown:
//
// The network-processing threads are all part of a thread group
2017-03-09 17:04:59 -08:00
// created by AppInit().
2013-03-09 09:02:57 -08:00
//
// A clean exit happens when StartShutdown() or the SIGTERM
// signal handler sets fRequestShutdown, which triggers
// the DetectShutdownThread(), which interrupts the main thread group.
// DetectShutdownThread() then exits, which causes AppInit() to
// continue (it .joins the shutdown thread).
// Shutdown() is then
// called to clean up database connections, and stop other
// threads that should only be stopped after the main network-processing
// threads have exited.
//
// Note that if running -daemon the parent process returns from AppInit2
// before adding any threads to the threadGroup, so .join_all() returns
// immediately and the parent exits from main().
//
2016-05-30 06:39:37 -07:00
std : : atomic < bool > fRequestShutdown ( false ) ;
2011-05-14 11:10:21 -07:00
2012-06-10 22:40:14 -07:00
void StartShutdown ( )
{
2013-03-09 09:02:57 -08:00
fRequestShutdown = true ;
2012-06-10 22:40:14 -07:00
}
2013-03-23 15:14:12 -07:00
bool ShutdownRequested ( )
{
return fRequestShutdown ;
}
2012-06-10 22:40:14 -07:00
2015-01-08 05:38:06 -08:00
class CCoinsViewErrorCatcher : public CCoinsViewBacked
{
public :
CCoinsViewErrorCatcher ( CCoinsView * view ) : CCoinsViewBacked ( view ) { }
bool GetCoins ( const uint256 & txid , CCoins & coins ) const {
try {
return CCoinsViewBacked : : GetCoins ( txid , coins ) ;
} catch ( const std : : runtime_error & e ) {
uiInterface . ThreadSafeMessageBox ( _ ( " Error reading from database, shutting down. " ) , " " , CClientUIInterface : : MSG_ERROR ) ;
LogPrintf ( " Error reading from database: %s \n " , e . what ( ) ) ;
// Starting the shutdown sequence and returning false to the caller would be
// interpreted as 'entry not found' (as opposed to unable to read data), and
2015-02-10 20:24:38 -08:00
// could lead to invalid interpretation. Just exit immediately, as we can't
2015-01-08 05:38:06 -08:00
// continue anyway, and all writes should be atomic.
abort ( ) ;
}
}
// Writes do not need similar protection, as failure to write is handled by the caller.
} ;
2014-09-25 00:03:30 -07:00
static CCoinsViewDB * pcoinsdbview = NULL ;
2015-01-08 05:38:06 -08:00
static CCoinsViewErrorCatcher * pcoinscatcher = NULL ;
2015-07-28 11:11:20 -07:00
static boost : : scoped_ptr < ECCVerifyHandle > globalVerifyHandle ;
2012-07-06 07:33:34 -07:00
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
void Interrupt ( boost : : thread_group & threadGroup )
{
InterruptHTTPServer ( ) ;
InterruptHTTPRPC ( ) ;
InterruptRPC ( ) ;
InterruptREST ( ) ;
2015-09-08 08:48:45 -07:00
InterruptTorControl ( ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
threadGroup . interrupt_all ( ) ;
}
2013-03-09 09:02:57 -08:00
void Shutdown ( )
2011-05-14 11:10:21 -07:00
{
2020-08-11 06:38:23 -07:00
auto span = TracingSpan ( " info " , " main " , " Shutdown " ) ;
auto spanGuard = span . Enter ( ) ;
2011-05-14 11:10:21 -07:00
static CCriticalSection cs_Shutdown ;
2013-03-09 09:02:57 -08:00
TRY_LOCK ( cs_Shutdown , lockShutdown ) ;
2014-06-27 05:41:11 -07:00
if ( ! lockShutdown )
return ;
2012-06-24 08:03:57 -07:00
2014-09-18 05:08:43 -07:00
/// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way,
/// for example if the data directory was found to be locked.
/// Be sure that anything that writes files or flushes caches only does this if the respective
/// module was initialized.
2016-10-26 12:57:22 -07:00
RenameThread ( " zcash-shutoff " ) ;
2013-08-26 22:51:57 -07:00
mempool . AddTransactionsUpdated ( 1 ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
StopHTTPRPC ( ) ;
StopREST ( ) ;
StopRPC ( ) ;
StopHTTPServer ( ) ;
2013-12-08 06:26:08 -08:00
# ifdef ENABLE_WALLET
2013-08-24 21:00:02 -07:00
if ( pwalletMain )
2015-02-04 12:19:27 -08:00
pwalletMain - > Flush ( false ) ;
2016-12-22 20:30:27 -08:00
# endif
# ifdef ENABLE_MINING
2015-04-10 03:49:01 -07:00
GenerateBitcoins ( false , 0 , Params ( ) ) ;
2013-11-29 07:04:29 -08:00
# endif
2013-03-06 19:31:26 -08:00
StopNode ( ) ;
2015-08-25 11:12:08 -07:00
StopTorControl ( ) ;
2013-11-17 16:25:17 -08:00
UnregisterNodeSignals ( GetNodeSignals ( ) ) ;
2014-03-17 05:19:54 -07:00
2014-09-18 05:08:43 -07:00
if ( fFeeEstimatesInitialized )
2014-07-16 12:46:01 -07:00
{
2017-03-01 08:05:50 -08:00
fs : : path est_path = GetDataDir ( ) / FEE_ESTIMATES_FILENAME ;
2017-03-01 08:28:39 -08:00
CAutoFile est_fileout ( fsbridge : : fopen ( est_path , " wb " ) , SER_DISK , CLIENT_VERSION ) ;
2014-10-20 03:45:50 -07:00
if ( ! est_fileout . IsNull ( ) )
2014-07-16 12:46:01 -07:00
mempool . WriteFeeEstimates ( est_fileout ) ;
else
LogPrintf ( " %s: Failed to write fee estimates to %s \n " , __func__ , est_path . string ( ) ) ;
2014-09-18 05:08:43 -07:00
fFeeEstimatesInitialized = false ;
2014-07-16 12:46:01 -07:00
}
2014-03-17 05:19:54 -07:00
2011-05-14 11:10:21 -07:00
{
2013-03-09 09:02:57 -08:00
LOCK ( cs_main ) ;
Improve chainstate/blockindex disk writing policy
There are 3 pieces of data that are maintained on disk. The actual block
and undo data, the block index (which can refer to positions on disk),
and the chainstate (which refers to the best block hash).
Earlier, there was no guarantee that blocks were written to disk before
block index entries referring to them were written. This commit introduces
dirty flags for block index data, and delays writing entries until the actual
block data is flushed.
With this stricter ordering in writes, it is now safe to not always flush
after every block, so there is no need for the IsInitialBlockDownload()
check there - instead we just write whenever enough time has passed or
the cache size grows too large. Also updating the wallet's best known block
is delayed until this is done, otherwise the wallet may end up referring to an
unknown block.
In addition, only do a write inside the block processing loop if necessary
(because of cache size exceeded). Otherwise, move the writing to a point
after processing is done, after relaying.
2014-11-07 02:38:35 -08:00
if ( pcoinsTip ! = NULL ) {
FlushStateToDisk ( ) ;
}
2014-06-27 05:41:11 -07:00
delete pcoinsTip ;
pcoinsTip = NULL ;
2015-01-08 05:38:06 -08:00
delete pcoinscatcher ;
pcoinscatcher = NULL ;
2014-06-27 05:41:11 -07:00
delete pcoinsdbview ;
pcoinsdbview = NULL ;
delete pblocktree ;
pblocktree = NULL ;
2011-05-14 11:10:21 -07:00
}
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2013-08-24 21:00:02 -07:00
if ( pwalletMain )
2015-02-04 12:19:27 -08:00
pwalletMain - > Flush ( true ) ;
2013-11-29 07:04:29 -08:00
# endif
2014-11-18 09:06:32 -08:00
# if ENABLE_ZMQ
if ( pzmqNotificationInterface ) {
UnregisterValidationInterface ( pzmqNotificationInterface ) ;
delete pzmqNotificationInterface ;
pzmqNotificationInterface = NULL ;
}
# endif
2014-09-20 01:56:25 -07:00
# ifndef WIN32
2015-05-18 16:37:43 -07:00
try {
2017-03-01 08:05:50 -08:00
fs : : remove ( GetPidFile ( ) ) ;
} catch ( const fs : : filesystem_error & e ) {
2015-05-18 16:37:43 -07:00
LogPrintf ( " %s: Unable to remove pidfile: %s \n " , __func__ , e . what ( ) ) ;
}
2014-09-20 01:56:25 -07:00
# endif
2014-10-19 18:17:01 -07:00
UnregisterAllValidationInterfaces ( ) ;
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2014-09-25 00:03:30 -07:00
delete pwalletMain ;
pwalletMain = NULL ;
2013-11-29 07:04:29 -08:00
# endif
2015-07-28 11:11:20 -07:00
globalVerifyHandle . reset ( ) ;
Update key.cpp to use new libsecp256k1
libsecp256k1's API changed, so update key.cpp to use it.
Libsecp256k1 now has explicit context objects, which makes it completely thread-safe.
In turn, keep an explicit context object in key.cpp, which is explicitly initialized
destroyed. This is not really pretty now, but it's more efficient than the static
initialized object in key.cpp (which made for example bitcoin-tx slow, as for most of
its calls, libsecp256k1 wasn't actually needed).
This also brings in the new blinding support in libsecp256k1. By passing in a random
seed, temporary variables during the elliptic curve computations are altered, in such
a way that if an attacker does not know the blind, observing the internal operations
leaks less information about the keys used. This was implemented by Greg Maxwell.
2015-04-22 14:28:26 -07:00
ECC_Stop ( ) ;
2020-08-11 06:38:23 -07:00
TracingInfo ( " main " , " done " ) ;
2020-07-10 05:51:40 -07:00
if ( pTracingHandle ) {
tracing_free ( pTracingHandle ) ;
}
2011-05-14 11:10:21 -07:00
}
2014-11-30 17:39:44 -08:00
/**
* Signal handlers are very limited in what they are allowed to do , so :
*/
2011-05-14 11:10:21 -07:00
void HandleSIGTERM ( int )
{
fRequestShutdown = true ;
}
2012-03-02 11:31:16 -08:00
void HandleSIGHUP ( int )
{
fReopenDebugLog = true ;
}
2011-05-14 11:10:21 -07:00
2012-05-13 03:35:39 -07:00
bool static InitError ( const std : : string & str )
{
2014-07-14 01:46:06 -07:00
uiInterface . ThreadSafeMessageBox ( str , " " , CClientUIInterface : : MSG_ERROR ) ;
2012-05-13 03:35:39 -07:00
return false ;
}
bool static InitWarning ( const std : : string & str )
{
2014-07-14 01:46:06 -07:00
uiInterface . ThreadSafeMessageBox ( str , " " , CClientUIInterface : : MSG_WARNING ) ;
2012-05-13 03:35:39 -07:00
return true ;
}
2012-11-14 07:07:40 -08:00
bool static Bind ( const CService & addr , unsigned int flags ) {
2012-09-03 06:54:47 -07:00
if ( ! ( flags & BF_EXPLICIT ) & & IsLimited ( addr ) )
2012-05-11 06:28:59 -07:00
return false ;
std : : string strError ;
2014-09-06 12:59:59 -07:00
if ( ! BindListenPort ( addr , strError , ( flags & BF_WHITELIST ) ! = 0 ) ) {
2012-09-03 06:54:47 -07:00
if ( flags & BF_REPORT_ERROR )
2012-05-24 10:02:21 -07:00
return InitError ( strError ) ;
return false ;
}
2012-05-11 06:28:59 -07:00
return true ;
}
2014-10-19 01:46:17 -07:00
void OnRPCStopped ( )
{
2018-04-03 21:53:07 -07:00
g_best_block_cv . notify_all ( ) ;
2014-10-19 01:46:17 -07:00
LogPrint ( " rpc " , " RPC stopped. \n " ) ;
}
void OnRPCPreCommand ( const CRPCCommand & cmd )
{
// Observe safe mode
2017-01-27 00:43:41 -08:00
std : : string strWarning = GetWarnings ( " rpc " ) . first ;
2015-11-09 10:16:38 -08:00
if ( strWarning ! = " " & & ! GetBoolArg ( " -disablesafemode " , DEFAULT_DISABLE_SAFEMODE ) & &
2014-10-19 01:46:17 -07:00
! cmd . okSafeMode )
2017-01-27 00:43:41 -08:00
throw JSONRPCError ( RPC_FORBIDDEN_BY_SAFE_MODE , std : : string ( " Safe mode: " ) + strWarning ) ;
2014-10-19 01:46:17 -07:00
}
2014-06-17 00:13:52 -07:00
std : : string HelpMessage ( HelpMessageMode mode )
2012-05-13 02:36:10 -07:00
{
2015-06-12 06:12:14 -07:00
const bool showDebug = GetBoolArg ( " -help-debug " , false ) ;
2015-02-04 00:11:49 -08:00
2014-06-17 00:13:52 -07:00
// When adding new options to the categories, please keep and ensure alphabetical ordering.
2018-03-02 03:45:05 -08:00
// Do not translate _(...) -help-debug options, many technical terms, and only a very small audience, so is unnecessary stress to translators
2015-06-12 06:12:14 -07:00
2017-01-27 00:43:41 -08:00
std : : string strUsage = HelpMessageGroup ( _ ( " Options: " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -? " , _ ( " This help message " ) ) ;
2015-06-12 03:00:39 -07:00
strUsage + = HelpMessageOpt ( " -alerts " , strprintf ( _ ( " Receive and display P2P network alerts (default: %u) " ) , DEFAULT_ALERTS ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -alertnotify=<cmd> " , _ ( " Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) " ) ) ;
strUsage + = HelpMessageOpt ( " -blocknotify=<cmd> " , _ ( " Execute command when the best block changes (%s in cmd is replaced by block hash) " ) ) ;
2015-11-14 04:47:53 -08:00
if ( showDebug )
2020-03-29 00:29:15 -07:00
strUsage + = HelpMessageOpt ( " -blocksonly " , strprintf ( _ ( " Whether to reject transactions from network peers. Automatic broadcast and rebroadcast of any transactions from inbound peers is disabled, unless '-whitelistforcerelay' is '1', in which case whitelisted peers' transactions will be relayed. RPC transactions are not affected. (default: %u) " ) , DEFAULT_BLOCKSONLY ) ) ;
2015-06-27 12:08:36 -07:00
strUsage + = HelpMessageOpt ( " -checkblocks=<n> " , strprintf ( _ ( " How many blocks to check at startup (default: %u, 0 = all) " ) , DEFAULT_CHECKBLOCKS ) ) ;
strUsage + = HelpMessageOpt ( " -checklevel=<n> " , strprintf ( _ ( " How thorough the block verification of -checkblocks is (0-4, default: %u) " ) , DEFAULT_CHECKLEVEL ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -conf=<file> " , strprintf ( _ ( " Specify configuration file (default: %s) " ) , BITCOIN_CONF_FILENAME ) ) ;
2014-06-17 00:13:52 -07:00
if ( mode = = HMM_BITCOIND )
2014-02-02 22:23:20 -08:00
{
2015-09-11 14:31:30 -07:00
# ifndef WIN32
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -daemon " , _ ( " Run in the background as a daemon and accept commands " ) ) ;
2014-02-02 22:23:20 -08:00
# endif
}
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -datadir=<dir> " , _ ( " Specify data directory " ) ) ;
2018-12-21 13:37:18 -08:00
strUsage + = HelpMessageOpt ( " -paramsdir=<dir> " , _ ( " Specify Zcash network parameters directory " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -dbcache=<n> " , strprintf ( _ ( " Set database cache size in megabytes (%d to %d, default: %d) " ) , nMinDbCache , nMaxDbCache , nDefaultDbCache ) ) ;
2017-11-28 01:31:52 -08:00
strUsage + = HelpMessageOpt ( " -debuglogfile=<file> " , strprintf ( _ ( " Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s) " ) , DEFAULT_DEBUGLOGFILE ) ) ;
2020-05-04 11:11:29 -07:00
strUsage + = HelpMessageOpt ( " -exportdir=<dir> " , _ ( " Specify directory to be used when exporting data " ) ) ;
2020-10-13 06:18:51 -07:00
strUsage + = HelpMessageOpt ( " -ibdskiptxverification " , strprintf ( _ ( " Skip transaction verification during initial block download up to the last checkpoint height. Incompatible with flags that disable checkpoints. (default = %u) " ) , DEFAULT_IBD_SKIP_TX_VERIFICATION ) ) ;
2020-05-04 11:11:29 -07:00
strUsage + = HelpMessageOpt ( " -loadblock=<file> " , _ ( " Imports blocks from external blk000??.dat file on startup " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -maxorphantx=<n> " , strprintf ( _ ( " Keep at most <n> unconnectable transactions in memory (default: %u) " ) , DEFAULT_MAX_ORPHAN_TRANSACTIONS ) ) ;
strUsage + = HelpMessageOpt ( " -par=<n> " , strprintf ( _ ( " Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) " ) ,
2015-07-01 08:38:15 -07:00
- GetNumCores ( ) , MAX_SCRIPTCHECK_THREADS , DEFAULT_SCRIPTCHECK_THREADS ) ) ;
2014-09-20 01:56:25 -07:00
# ifndef WIN32
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -pid=<file> " , strprintf ( _ ( " Specify pid file (default: %s) " ) , BITCOIN_PID_FILENAME ) ) ;
2014-09-20 01:56:25 -07:00
# endif
2015-05-04 09:46:33 -07:00
strUsage + = HelpMessageOpt ( " -prune=<n> " , strprintf ( _ ( " Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. "
" Warning: Reverting this setting requires re-downloading the entire blockchain. "
" (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) " ) , MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024 ) ) ;
2016-04-21 05:14:37 -07:00
strUsage + = HelpMessageOpt ( " -reindex-chainstate " , _ ( " Rebuild chain state from the currently indexed blocks " ) ) ;
strUsage + = HelpMessageOpt ( " -reindex " , _ ( " Rebuild chain state and block index from the blk*.dat files on disk " ) ) ;
2015-09-11 14:31:30 -07:00
# ifndef WIN32
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -sysperms " , _ ( " Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) " ) ) ;
2014-06-04 04:16:07 -07:00
# endif
2020-02-10 14:44:20 -08:00
strUsage + = HelpMessageOpt ( " -txexpirynotify=<cmd> " , _ ( " Execute command when transaction expires (%s in cmd is replaced by transaction id) " ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -txindex " , strprintf ( _ ( " Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) " ) , DEFAULT_TXINDEX ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageGroup ( _ ( " Connection options: " ) ) ;
strUsage + = HelpMessageOpt ( " -addnode=<ip> " , _ ( " Add a node to connect to and attempt to keep the connection open " ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -banscore=<n> " , strprintf ( _ ( " Threshold for disconnecting misbehaving peers (default: %u) " ) , DEFAULT_BANSCORE_THRESHOLD ) ) ;
strUsage + = HelpMessageOpt ( " -bantime=<n> " , strprintf ( _ ( " Number of seconds to keep misbehaving peers from reconnecting (default: %u) " ) , DEFAULT_MISBEHAVING_BANTIME ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -bind=<addr> " , _ ( " Bind to given address and always listen on it. Use [host]:port notation for IPv6 " ) ) ;
2016-10-23 18:21:04 -07:00
strUsage + = HelpMessageOpt ( " -connect=<ip> " , _ ( " Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -discover " , _ ( " Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) " ) ) ;
2015-11-09 10:16:38 -08:00
strUsage + = HelpMessageOpt ( " -dns " , _ ( " Allow DNS lookups for -addnode, -seednode and -connect " ) + " " + strprintf ( _ ( " (default: %u) " ) , DEFAULT_NAME_LOOKUP ) ) ;
2016-10-23 18:21:04 -07:00
strUsage + = HelpMessageOpt ( " -dnsseed " , _ ( " Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect) " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -externalip=<ip> " , _ ( " Specify your own public address " ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -forcednsseed " , strprintf ( _ ( " Always query for peer addresses via DNS lookup (default: %u) " ) , DEFAULT_FORCEDNSSEED ) ) ;
2016-10-23 18:21:04 -07:00
strUsage + = HelpMessageOpt ( " -listen " , _ ( " Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect) " ) ) ;
2015-08-25 11:12:08 -07:00
strUsage + = HelpMessageOpt ( " -listenonion " , strprintf ( _ ( " Automatically create Tor hidden service (default: %d) " ) , DEFAULT_LISTEN_ONION ) ) ;
2015-08-01 10:41:21 -07:00
strUsage + = HelpMessageOpt ( " -maxconnections=<n> " , strprintf ( _ ( " Maintain at most <n> connections to peers (default: %u) " ) , DEFAULT_MAX_PEER_CONNECTIONS ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -maxreceivebuffer=<n> " , strprintf ( _ ( " Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) " ) , DEFAULT_MAXRECEIVEBUFFER ) ) ;
strUsage + = HelpMessageOpt ( " -maxsendbuffer=<n> " , strprintf ( _ ( " Maximum per-connection send buffer, <n>*1000 bytes (default: %u) " ) , DEFAULT_MAXSENDBUFFER ) ) ;
2019-10-21 08:20:17 -07:00
strUsage + = HelpMessageOpt ( " -mempoolevictionmemoryminutes=<n> " , strprintf ( _ ( " The number of minutes before allowing rejected transactions to re-enter the mempool. (default: %u) " ) , DEFAULT_MEMPOOL_EVICTION_MEMORY_MINUTES ) ) ;
strUsage + = HelpMessageOpt ( " -mempooltxcostlimit=<n> " , strprintf ( _ ( " An upper bound on the maximum size in bytes of all transactions in the mempool. (default: %s) " ) , DEFAULT_MEMPOOL_TOTAL_COST_LIMIT ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -onion=<ip:port> " , strprintf ( _ ( " Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) " ) , " -proxy " ) ) ;
strUsage + = HelpMessageOpt ( " -onlynet=<net> " , _ ( " Only connect to nodes in network <net> (ipv4, ipv6 or onion) " ) ) ;
2015-11-09 10:16:38 -08:00
strUsage + = HelpMessageOpt ( " -permitbaremultisig " , strprintf ( _ ( " Relay non-P2SH multisig (default: %u) " ) , DEFAULT_PERMIT_BAREMULTISIG ) ) ;
2016-02-10 22:35:25 -08:00
strUsage + = HelpMessageOpt ( " -peerbloomfilters " , strprintf ( _ ( " Support filtering of blocks and transaction with bloom filters (default: %u) " ) , DEFAULT_PEERBLOOMFILTERS ) ) ;
2015-11-24 01:57:08 -08:00
if ( showDebug )
2016-02-10 22:35:25 -08:00
strUsage + = HelpMessageOpt ( " -enforcenodebloom " , strprintf ( " Enforce minimum protocol version to limit use of bloom filters (default: %u) " , DEFAULT_ENFORCENODEBLOOM ) ) ;
2018-03-27 08:08:36 -07:00
strUsage + = HelpMessageOpt ( " -port=<port> " , strprintf ( _ ( " Listen for connections on <port> (default: %u or testnet: %u) " ) ,
Params ( CBaseChainParams : : MAIN ) . GetDefaultPort ( ) , Params ( CBaseChainParams : : TESTNET ) . GetDefaultPort ( ) ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -proxy=<ip:port> " , _ ( " Connect through SOCKS5 proxy " ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -proxyrandomize " , strprintf ( _ ( " Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) " ) , DEFAULT_PROXYRANDOMIZE ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -seednode=<ip> " , _ ( " Connect to a node to retrieve peer addresses, and disconnect " ) ) ;
strUsage + = HelpMessageOpt ( " -timeout=<n> " , strprintf ( _ ( " Specify connection timeout in milliseconds (minimum: 1, default: %d) " ) , DEFAULT_CONNECT_TIMEOUT ) ) ;
2015-08-25 11:12:08 -07:00
strUsage + = HelpMessageOpt ( " -torcontrol=<ip>:<port> " , strprintf ( _ ( " Tor control port to use if onion listening enabled (default: %s) " ) , DEFAULT_TOR_CONTROL ) ) ;
2015-09-08 08:48:45 -07:00
strUsage + = HelpMessageOpt ( " -torpassword=<pass> " , _ ( " Tor control port password (default: empty) " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -whitebind=<addr> " , _ ( " Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 " ) ) ;
strUsage + = HelpMessageOpt ( " -whitelist=<netmask> " , _ ( " Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. " ) +
" " + _ ( " Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway " ) ) ;
2019-08-06 03:44:24 -07:00
strUsage + = HelpMessageOpt ( " -whitelistrelay " , strprintf ( _ ( " Accept relayed transactions received from whitelisted inbound peers even when not relaying transactions (default: %d) " ) , DEFAULT_WHITELISTRELAY ) ) ;
strUsage + = HelpMessageOpt ( " -whitelistforcerelay " , strprintf ( _ ( " Force relay of transactions from whitelisted inbound peers even they violate local relay policy (default: %d) " ) , DEFAULT_WHITELISTFORCERELAY ) ) ;
2015-11-05 15:05:06 -08:00
strUsage + = HelpMessageOpt ( " -maxuploadtarget=<n> " , strprintf ( _ ( " Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) " ) , DEFAULT_MAX_UPLOAD_TARGET ) ) ;
2014-02-02 22:23:20 -08:00
# ifdef ENABLE_WALLET
2016-02-22 01:48:44 -08:00
strUsage + = CWallet : : GetWalletHelpString ( showDebug ) ;
2014-02-02 22:23:20 -08:00
# endif
2014-11-18 09:06:32 -08:00
# if ENABLE_ZMQ
strUsage + = HelpMessageGroup ( _ ( " ZeroMQ notification options: " ) ) ;
strUsage + = HelpMessageOpt ( " -zmqpubhashblock=<address> " , _ ( " Enable publish hash block in <address> " ) ) ;
2015-11-18 17:34:19 -08:00
strUsage + = HelpMessageOpt ( " -zmqpubhashtx=<address> " , _ ( " Enable publish hash transaction in <address> " ) ) ;
2014-11-18 09:06:32 -08:00
strUsage + = HelpMessageOpt ( " -zmqpubrawblock=<address> " , _ ( " Enable publish raw block in <address> " ) ) ;
2015-11-18 17:34:19 -08:00
strUsage + = HelpMessageOpt ( " -zmqpubrawtx=<address> " , _ ( " Enable publish raw transaction in <address> " ) ) ;
2014-11-18 09:06:32 -08:00
# endif
2021-01-06 21:30:28 -08:00
strUsage + = HelpMessageGroup ( _ ( " Monitoring options: " ) ) ;
strUsage + = HelpMessageOpt ( " -metricsallowip=<ip> " , _ ( " Allow metrics connections from specified source. "
" Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). "
" This option can be specified multiple times. (default: only localhost) " ) ) ;
strUsage + = HelpMessageOpt ( " -metricsbind=<addr> " , _ ( " Bind to given address to listen for metrics connections. (default: bind to all interfaces) " ) ) ;
strUsage + = HelpMessageOpt ( " -prometheusport=<port> " , _ ( " Expose node metrics in the Prometheus exposition format. "
" An HTTP listener will be started on <port>, which responds to GET requests on any request path. "
" Use -metricsallowip and -metricsbind to control access. " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageGroup ( _ ( " Debugging/Testing options: " ) ) ;
2015-06-12 06:12:14 -07:00
if ( showDebug )
2014-02-02 22:23:20 -08:00
{
2015-11-09 10:16:38 -08:00
strUsage + = HelpMessageOpt ( " -checkpoints " , strprintf ( " Disable expensive verification for known chain history (default: %u) " , DEFAULT_CHECKPOINTS_ENABLED ) ) ;
strUsage + = HelpMessageOpt ( " -disablesafemode " , strprintf ( " Disable safemode, override a real safe mode event (default: %u) " , DEFAULT_DISABLE_SAFEMODE ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -testsafemode " , strprintf ( " Force safe mode (default: %u) " , DEFAULT_TESTSAFEMODE ) ) ;
2015-06-12 06:12:14 -07:00
strUsage + = HelpMessageOpt ( " -dropmessagestest=<n> " , " Randomly drop 1 of every <n> network messages " ) ;
strUsage + = HelpMessageOpt ( " -fuzzmessagestest=<n> " , " Randomly fuzz 1 of every <n> network messages " ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -stopafterblockimport " , strprintf ( " Stop running after importing blocks from disk (default: %u) " , DEFAULT_STOPAFTERBLOCKIMPORT ) ) ;
2018-01-31 12:11:18 -08:00
strUsage + = HelpMessageOpt ( " -nuparams=hexBranchId:activationHeight " , " Use given activation height for specified network upgrade (regtest-only) " ) ;
2019-12-13 09:24:56 -08:00
strUsage + = HelpMessageOpt ( " -nurejectoldversions " , strprintf ( " Reject peers that don't know about the current epoch (regtest-only) (default: %u) " , DEFAULT_NU_REJECT_OLD_VERSIONS ) ) ;
2020-06-05 14:46:45 -07:00
strUsage + = HelpMessageOpt (
2020-10-09 08:45:31 -07:00
" -fundingstream=streamId:startHeight:endHeight:comma_delimited_addresses " ,
2020-07-06 14:41:28 -07:00
" Use given addresses for block subsidy share paid to the funding stream with id <streamId> (regtest-only) " ) ;
2014-02-02 22:23:20 -08:00
}
2015-08-06 01:03:11 -07:00
std : : string debugCategories = " addrman, alert, bench, coindb, db, estimatefee, http, libevent, lock, mempool, mempoolrej, net, partitioncheck, pow, proxy, prune, "
2020-10-08 06:17:57 -07:00
" rand, receiveunsafe, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc) " ; // Don't translate these
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -debug=<category> " , strprintf ( _ ( " Output debugging information (default: %u, supplying <category> is optional) " ) , 0 ) + " . " +
2020-10-09 08:45:31 -07:00
_ ( " If <category> is not supplied or if <category> = 1, output all debugging information. " ) + " " + _ ( " <category> can be: " ) + " " + debugCategories + " . " +
2020-04-06 05:09:43 -07:00
_ ( " For multiple specific categories use -debug=<category> multiple times. " ) ) ;
2017-01-31 14:28:33 -08:00
strUsage + = HelpMessageOpt ( " -experimentalfeatures " , _ ( " Enable use of experimental features " ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -help-debug " , _ ( " Show all debugging options (usage: --help -help-debug) " ) ) ;
2015-11-09 10:16:38 -08:00
strUsage + = HelpMessageOpt ( " -logips " , strprintf ( _ ( " Include IP addresses in debug output (default: %u) " ) , DEFAULT_LOGIPS ) ) ;
strUsage + = HelpMessageOpt ( " -logtimestamps " , strprintf ( _ ( " Prepend debug output with timestamp (default: %u) " ) , DEFAULT_LOGTIMESTAMPS ) ) ;
2015-06-12 06:12:14 -07:00
if ( showDebug )
2013-10-08 03:09:40 -07:00
{
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -limitfreerelay=<n> " , strprintf ( " Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u) " , DEFAULT_LIMITFREERELAY ) ) ;
strUsage + = HelpMessageOpt ( " -relaypriority " , strprintf ( " Require high priority for relaying free or low-fee transactions (default: %u) " , DEFAULT_RELAYPRIORITY ) ) ;
2015-10-30 15:14:38 -07:00
strUsage + = HelpMessageOpt ( " -maxsigcachesize=<n> " , strprintf ( " Limit size of signature cache to <n> MiB (default: %u) " , DEFAULT_MAX_SIG_CACHE_SIZE ) ) ;
2015-12-14 04:23:45 -08:00
strUsage + = HelpMessageOpt ( " -maxtipage=<n> " , strprintf ( " Maximum tip age in seconds to consider node in initial block download (default: %u) " , DEFAULT_MAX_TIP_AGE ) ) ;
2013-10-08 03:09:40 -07:00
}
2015-10-24 19:01:20 -07:00
strUsage + = HelpMessageOpt ( " -minrelaytxfee=<amt> " , strprintf ( _ ( " Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) " ) ,
2015-11-05 23:33:14 -08:00
CURRENCY_UNIT , FormatMoney ( DEFAULT_MIN_RELAY_TX_FEE ) ) ) ;
2015-11-23 11:32:36 -08:00
strUsage + = HelpMessageOpt ( " -maxtxfee=<amt> " , strprintf ( _ ( " Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) " ) ,
CURRENCY_UNIT , FormatMoney ( DEFAULT_TRANSACTION_MAXFEE ) ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -printtoconsole " , _ ( " Send trace/debug info to console instead of debug.log file " ) ) ;
2015-06-12 06:12:14 -07:00
if ( showDebug )
2013-10-08 03:09:40 -07:00
{
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -printpriority " , strprintf ( " Log transaction priority and fee per kB when mining blocks (default: %u) " , DEFAULT_PRINTPRIORITY ) ) ;
2013-10-08 03:09:40 -07:00
}
2019-09-19 10:05:56 -07:00
// strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
2015-05-25 00:00:17 -07:00
AppendParamsHelpMessages ( strUsage , showDebug ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageGroup ( _ ( " Node relay options: " ) ) ;
2015-11-09 10:16:38 -08:00
strUsage + = HelpMessageOpt ( " -datacarrier " , strprintf ( _ ( " Relay and mine data carrier transactions (default: %u) " ) , DEFAULT_ACCEPT_DATACARRIER ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -datacarriersize " , strprintf ( _ ( " Maximum size of data in data carrier transactions we relay and mine (default: %u) " ) , MAX_OP_RETURN_RELAY ) ) ;
strUsage + = HelpMessageGroup ( _ ( " Block creation options: " ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -blockminsize=<n> " , strprintf ( _ ( " Set minimum block size in bytes (default: %u) " ) , DEFAULT_BLOCK_MIN_SIZE ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -blockmaxsize=<n> " , strprintf ( _ ( " Set maximum block size in bytes (default: %d) " ) , DEFAULT_BLOCK_MAX_SIZE ) ) ;
strUsage + = HelpMessageOpt ( " -blockprioritysize=<n> " , strprintf ( _ ( " Set maximum size of high-priority/low-fee transactions in bytes (default: %d) " ) , DEFAULT_BLOCK_PRIORITY_SIZE ) ) ;
2015-06-01 05:37:21 -07:00
if ( GetBoolArg ( " -help-debug " , false ) )
strUsage + = HelpMessageOpt ( " -blockversion=<n> " , strprintf ( " Override block version to test forking scenarios (default: %d) " , ( int ) CBlock : : CURRENT_VERSION ) ) ;
2015-02-04 00:11:49 -08:00
2017-01-27 03:24:30 -08:00
# ifdef ENABLE_MINING
strUsage + = HelpMessageGroup ( _ ( " Mining options: " ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -gen " , strprintf ( _ ( " Generate coins (default: %u) " ) , DEFAULT_GENERATE ) ) ;
2015-06-27 16:48:38 -07:00
strUsage + = HelpMessageOpt ( " -genproclimit=<n> " , strprintf ( _ ( " Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) " ) , DEFAULT_GENERATE_THREADS ) ) ;
2017-01-27 03:24:30 -08:00
strUsage + = HelpMessageOpt ( " -equihashsolver=<name> " , _ ( " Specify the Equihash solver to be used if enabled (default: \" default \" ) " ) ) ;
strUsage + = HelpMessageOpt ( " -mineraddress=<addr> " , _ ( " Send mined coins to a specific single address " ) ) ;
2017-01-30 08:24:07 -08:00
strUsage + = HelpMessageOpt ( " -minetolocalwallet " , strprintf (
_ ( " Require that mined blocks use a coinbase address in the local wallet (default: %u) " ) ,
# ifdef ENABLE_WALLET
1
# else
0
# endif
) ) ;
2017-01-27 03:24:30 -08:00
# endif
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageGroup ( _ ( " RPC server options: " ) ) ;
strUsage + = HelpMessageOpt ( " -server " , _ ( " Accept command line and JSON-RPC commands " ) ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -rest " , strprintf ( _ ( " Accept public REST requests (default: %u) " ) , DEFAULT_REST_ENABLE ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -rpcbind=<addr> " , _ ( " Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) " ) ) ;
strUsage + = HelpMessageOpt ( " -rpcuser=<user> " , _ ( " Username for JSON-RPC connections " ) ) ;
strUsage + = HelpMessageOpt ( " -rpcpassword=<pw> " , _ ( " Password for JSON-RPC connections " ) ) ;
2015-11-11 07:49:32 -08:00
strUsage + = HelpMessageOpt ( " -rpcauth=<userpw> " , _ ( " Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times " ) ) ;
2016-06-15 19:14:27 -07:00
strUsage + = HelpMessageOpt ( " -rpcport=<port> " , strprintf ( _ ( " Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) " ) , 8232 , 18232 ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -rpcallowip=<ip> " , _ ( " Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times " ) ) ;
2015-08-28 08:14:51 -07:00
strUsage + = HelpMessageOpt ( " -rpcthreads=<n> " , strprintf ( _ ( " Set the number of threads to service RPC calls (default: %d) " ) , DEFAULT_HTTP_THREADS ) ) ;
if ( showDebug ) {
strUsage + = HelpMessageOpt ( " -rpcworkqueue=<n> " , strprintf ( " Set the depth of the work queue to service RPC calls (default: %d) " , DEFAULT_HTTP_WORKQUEUE ) ) ;
2015-09-18 06:45:38 -07:00
strUsage + = HelpMessageOpt ( " -rpcservertimeout=<n> " , strprintf ( " Timeout during HTTP requests (default: %d) " , DEFAULT_HTTP_SERVER_TIMEOUT ) ) ;
2015-08-28 08:14:51 -07:00
}
2016-09-01 17:02:11 -07:00
2019-06-25 07:39:16 -07:00
// Disabled until we can lock notes and also tune performance of the prover which by default uses multiple threads
2016-09-01 17:02:11 -07:00
//strUsage += HelpMessageOpt("-rpcasyncthreads=<n>", strprintf(_("Set the number of threads to service Async RPC calls (default: %d)"), 1));
2015-02-04 00:11:49 -08:00
2017-03-09 17:04:59 -08:00
if ( mode = = HMM_BITCOIND ) {
2016-11-28 21:11:25 -08:00
strUsage + = HelpMessageGroup ( _ ( " Metrics Options (only if -daemon and -printtoconsole are not set): " ) ) ;
2016-11-17 19:49:37 -08:00
strUsage + = HelpMessageOpt ( " -showmetrics " , _ ( " Show metrics on stdout (default: 1 if running in a console, 0 otherwise) " ) ) ;
strUsage + = HelpMessageOpt ( " -metricsui " , _ ( " Set to 1 for a persistent metrics screen, 0 for sequential metrics output (default: 1 if running in a console, 0 otherwise) " ) ) ;
strUsage + = HelpMessageOpt ( " -metricsrefreshtime " , strprintf ( _ ( " Number of seconds between metrics refreshes (default: %u if running in a console, %u otherwise) " ) , 1 , 600 ) ) ;
2015-03-09 00:29:59 -07:00
}
2012-05-13 02:36:10 -07:00
return strUsage ;
}
2015-11-26 06:48:26 -08:00
static void BlockNotifyCallback ( bool initialSync , const CBlockIndex * pBlockIndex )
2014-08-14 09:32:34 -07:00
{
2015-11-26 06:48:26 -08:00
if ( initialSync | | ! pBlockIndex )
return ;
2014-08-14 09:32:34 -07:00
std : : string strCmd = GetArg ( " -blocknotify " , " " ) ;
2015-11-26 06:48:26 -08:00
boost : : replace_all ( strCmd , " %s " , pBlockIndex - > GetBlockHash ( ) . GetHex ( ) ) ;
2014-08-14 09:32:34 -07:00
boost : : thread t ( runCommand , strCmd ) ; // thread runs free
}
2020-02-10 14:44:20 -08:00
static void TxExpiryNotifyCallback ( const uint256 & txid )
{
std : : string strCmd = GetArg ( " -txexpirynotify " , " " ) ;
boost : : replace_all ( strCmd , " %s " , txid . GetHex ( ) ) ;
boost : : thread t ( runCommand , strCmd ) ; // thread runs free
}
2012-10-22 13:45:26 -07:00
struct CImportingNow
{
CImportingNow ( ) {
assert ( fImporting = = false ) ;
fImporting = true ;
}
~ CImportingNow ( ) {
assert ( fImporting = = true ) ;
fImporting = false ;
}
} ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
// If we're using -prune with -reindex, then delete block files that will be ignored by the
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
2015-06-02 12:24:53 -07:00
// is missing, do the same here to delete any later block files after a gap. Also delete all
// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
// is in sync with what's actually on disk by the time we start downloading, so that pruning
// works correctly.
void CleanupBlockRevFiles ( )
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
{
2017-03-01 08:05:50 -08:00
using namespace fs ;
2017-01-27 00:43:41 -08:00
std : : map < std : : string , path > mapBlockFiles ;
2015-06-02 12:24:53 -07:00
// Glob all blk?????.dat and rev?????.dat files from the blocks directory.
// Remove the rev files immediately and insert the blk file paths into an
// ordered map keyed by block file index.
LogPrintf ( " Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune \n " ) ;
path blocksdir = GetDataDir ( ) / " blocks " ;
for ( directory_iterator it ( blocksdir ) ; it ! = directory_iterator ( ) ; it + + ) {
if ( is_regular_file ( * it ) & &
it - > path ( ) . filename ( ) . string ( ) . length ( ) = = 12 & &
it - > path ( ) . filename ( ) . string ( ) . substr ( 8 , 4 ) = = " .dat " )
{
if ( it - > path ( ) . filename ( ) . string ( ) . substr ( 0 , 3 ) = = " blk " )
mapBlockFiles [ it - > path ( ) . filename ( ) . string ( ) . substr ( 3 , 5 ) ] = it - > path ( ) ;
else if ( it - > path ( ) . filename ( ) . string ( ) . substr ( 0 , 3 ) = = " rev " )
remove ( it - > path ( ) ) ;
}
}
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
2015-06-02 12:24:53 -07:00
// Remove all block files that aren't part of a contiguous set starting at
// zero by walking the ordered map (keys are block file indices) by
// keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
// start removing block files.
int nContigCounter = 0 ;
2017-01-27 00:43:41 -08:00
for ( const std : : pair < std : : string , path > & item : mapBlockFiles ) {
2015-06-02 12:24:53 -07:00
if ( atoi ( item . first ) = = nContigCounter ) {
nContigCounter + + ;
continue ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
}
2015-06-02 12:24:53 -07:00
remove ( item . second ) ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
}
}
2020-07-10 10:34:53 -07:00
void ThreadImport ( std : : vector < fs : : path > vImportFiles , const CChainParams & chainparams )
2013-03-06 19:31:26 -08:00
{
2016-10-26 12:57:22 -07:00
RenameThread ( " zcash-loadblk " ) ;
2016-04-20 06:45:41 -07:00
CImportingNow imp ;
2012-10-21 12:23:13 -07:00
// -reindex
if ( fReindex ) {
2020-02-20 07:40:46 -08:00
nSizeReindexed = 0 ; // will be modified inside LoadExternalBlockFile
// Find the summary size of all block files first
2012-10-21 12:23:13 -07:00
int nFile = 0 ;
2020-02-20 07:40:46 -08:00
size_t fullSize = 0 ;
while ( true ) {
CDiskBlockPos pos ( nFile , 0 ) ;
2017-03-01 08:05:50 -08:00
fs : : path blkFile = GetBlockPosFilename ( pos , " blk " ) ;
if ( ! fs : : exists ( blkFile ) )
2020-02-20 07:40:46 -08:00
break ; // No block files left to reindex
nFile + + ;
2017-03-01 08:05:50 -08:00
fullSize + = fs : : file_size ( blkFile ) ;
2020-02-20 07:40:46 -08:00
}
2020-03-16 07:56:38 -07:00
nFullSizeToReindex = std : : max < size_t > ( 1 , fullSize ) ;
2020-02-20 07:40:46 -08:00
nFile = 0 ;
2013-03-06 19:31:26 -08:00
while ( true ) {
2012-12-03 01:14:54 -08:00
CDiskBlockPos pos ( nFile , 0 ) ;
2017-03-01 08:05:50 -08:00
if ( ! fs : : exists ( GetBlockPosFilename ( pos , " blk " ) ) )
2014-09-08 10:29:14 -07:00
break ; // No block files left to reindex
2012-10-21 12:23:13 -07:00
FILE * file = OpenBlockFile ( pos , true ) ;
if ( ! file )
2014-09-08 10:29:14 -07:00
break ; // This error is logged in OpenBlockFile
2013-09-18 03:38:08 -07:00
LogPrintf ( " Reindexing block file blk%05u.dat... \n " , ( unsigned int ) nFile ) ;
2015-04-17 05:40:24 -07:00
LoadExternalBlockFile ( chainparams , file , & pos ) ;
2012-10-21 12:23:13 -07:00
nFile + + ;
}
2013-03-06 19:31:26 -08:00
pblocktree - > WriteReindexing ( false ) ;
fReindex = false ;
2020-02-20 07:40:46 -08:00
nSizeReindexed = 0 ;
nFullSizeToReindex = 1 ;
2013-09-18 03:38:08 -07:00
LogPrintf ( " Reindexing finished \n " ) ;
2013-03-06 19:31:26 -08:00
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
2015-04-17 05:40:24 -07:00
InitBlockIndex ( chainparams ) ;
2012-10-22 13:45:26 -07:00
}
// hardcoded $DATADIR/bootstrap.dat
2017-03-01 08:05:50 -08:00
fs : : path pathBootstrap = GetDataDir ( ) / " bootstrap.dat " ;
if ( fs : : exists ( pathBootstrap ) ) {
2017-03-01 08:28:39 -08:00
FILE * file = fsbridge : : fopen ( pathBootstrap , " rb " ) ;
2012-10-22 13:45:26 -07:00
if ( file ) {
2017-03-01 08:05:50 -08:00
fs : : path pathBootstrapOld = GetDataDir ( ) / " bootstrap.dat.old " ;
2013-09-18 03:38:08 -07:00
LogPrintf ( " Importing bootstrap.dat... \n " ) ;
2015-04-17 05:40:24 -07:00
LoadExternalBlockFile ( chainparams , file ) ;
2012-10-22 13:45:26 -07:00
RenameOver ( pathBootstrap , pathBootstrapOld ) ;
2014-02-08 02:35:02 -08:00
} else {
LogPrintf ( " Warning: Could not open bootstrap file %s \n " , pathBootstrap . string ( ) ) ;
2012-10-22 13:45:26 -07:00
}
}
2012-10-21 12:23:13 -07:00
// -loadblock=
2017-06-01 18:18:57 -07:00
for ( const fs : : path & path : vImportFiles ) {
2017-03-01 08:28:39 -08:00
FILE * file = fsbridge : : fopen ( path , " rb " ) ;
2012-10-21 12:23:13 -07:00
if ( file ) {
2014-02-08 02:35:02 -08:00
LogPrintf ( " Importing blocks file %s... \n " , path . string ( ) ) ;
2015-04-17 05:40:24 -07:00
LoadExternalBlockFile ( chainparams , file ) ;
2014-02-08 02:35:02 -08:00
} else {
LogPrintf ( " Warning: Could not open blocks file %s \n " , path . string ( ) ) ;
2012-10-21 12:23:13 -07:00
}
}
2014-05-07 11:10:48 -07:00
2016-04-20 06:45:41 -07:00
// scan for better chains in the block chain database, that are not yet connected in the active best chain
CValidationState state ;
if ( ! ActivateBestChain ( state , chainparams ) ) {
LogPrintf ( " Failed to connect best block " ) ;
StartShutdown ( ) ;
}
2015-06-27 12:21:41 -07:00
if ( GetBoolArg ( " -stopafterblockimport " , DEFAULT_STOPAFTERBLOCKIMPORT ) ) {
2014-05-07 11:10:48 -07:00
LogPrintf ( " Stopping after block import \n " ) ;
StartShutdown ( ) ;
}
2012-10-22 13:45:26 -07:00
}
2014-06-02 16:21:03 -07:00
/** Sanity checks
* Ensure that Bitcoin is running in a usable environment with all
* necessary library support .
*/
bool InitSanityCheck ( void )
{
2021-10-18 18:47:28 -07:00
if ( ! CKey : : ECC_InitSanityCheck ( ) ) {
2015-07-28 11:11:20 -07:00
InitError ( " Elliptic curve cryptography sanity check failure. Aborting. " ) ;
2014-06-02 16:21:03 -07:00
return false ;
}
2014-06-13 16:23:01 -07:00
if ( ! glibc_sanity_test ( ) | | ! glibcxx_sanity_test ( ) )
return false ;
2014-06-02 16:21:03 -07:00
return true ;
}
2016-01-04 06:30:53 -08:00
2018-04-17 13:44:53 -07:00
static void ZC_LoadParams (
const CChainParams & chainparams
)
2016-01-04 06:30:53 -08:00
{
struct timeval tv_start , tv_end ;
float elapsed ;
2017-03-01 08:05:50 -08:00
fs : : path sapling_spend = ZC_GetParamsDir ( ) / " sapling-spend.params " ;
fs : : path sapling_output = ZC_GetParamsDir ( ) / " sapling-output.params " ;
fs : : path sprout_groth16 = ZC_GetParamsDir ( ) / " sprout-groth16.params " ;
2016-01-04 06:30:53 -08:00
2018-04-17 13:44:53 -07:00
if ( ! (
2017-03-01 08:05:50 -08:00
fs : : exists ( sapling_spend ) & &
fs : : exists ( sapling_output ) & &
fs : : exists ( sprout_groth16 )
2018-04-17 13:44:53 -07:00
) ) {
2017-01-04 08:58:07 -08:00
uiInterface . ThreadSafeMessageBox ( strprintf (
_ ( " Cannot find the Zcash network parameters in the following directory: \n "
" %s \n "
2017-01-05 02:38:38 -08:00
" Please run 'zcash-fetch-params' or './zcutil/fetch-params.sh' and then restart. " ) ,
2017-01-04 08:58:07 -08:00
ZC_GetParamsDir ( ) ) ,
" " , CClientUIInterface : : MSG_ERROR ) ;
StartShutdown ( ) ;
return ;
}
2018-10-26 21:15:32 -07:00
static_assert (
2017-03-01 08:05:50 -08:00
sizeof ( fs : : path : : value_type ) = = sizeof ( codeunit ) ,
2018-10-26 21:15:32 -07:00
" librustzcash not configured correctly " ) ;
auto sapling_spend_str = sapling_spend . native ( ) ;
auto sapling_output_str = sapling_output . native ( ) ;
auto sprout_groth16_str = sprout_groth16 . native ( ) ;
LogPrintf ( " Loading Sapling (Spend) parameters from %s \n " , sapling_spend . string ( ) . c_str ( ) ) ;
LogPrintf ( " Loading Sapling (Output) parameters from %s \n " , sapling_output . string ( ) . c_str ( ) ) ;
LogPrintf ( " Loading Sapling (Sprout Groth16) parameters from %s \n " , sprout_groth16 . string ( ) . c_str ( ) ) ;
2018-08-04 15:28:39 -07:00
gettimeofday ( & tv_start , 0 ) ;
librustzcash_init_zksnark_params (
2018-10-26 21:15:32 -07:00
reinterpret_cast < const codeunit * > ( sapling_spend_str . c_str ( ) ) ,
sapling_spend_str . length ( ) ,
reinterpret_cast < const codeunit * > ( sapling_output_str . c_str ( ) ) ,
sapling_output_str . length ( ) ,
reinterpret_cast < const codeunit * > ( sprout_groth16_str . c_str ( ) ) ,
2020-08-25 03:08:08 -07:00
sprout_groth16_str . length ( )
2018-08-04 15:28:39 -07:00
) ;
gettimeofday ( & tv_end , 0 ) ;
elapsed = float ( tv_end . tv_sec - tv_start . tv_sec ) + ( tv_end . tv_usec - tv_start . tv_usec ) / float ( 1000000 ) ;
2021-06-21 05:16:34 -07:00
LogPrintf ( " Loaded proof system parameters in %fs seconds. \n " , elapsed ) ;
2016-01-04 06:30:53 -08:00
}
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
bool AppInitServers ( boost : : thread_group & threadGroup )
{
RPCServer : : OnStopped ( & OnRPCStopped ) ;
RPCServer : : OnPreCommand ( & OnRPCPreCommand ) ;
2015-08-28 07:55:16 -07:00
if ( ! InitHTTPServer ( ) )
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
return false ;
if ( ! StartRPC ( ) )
return false ;
if ( ! StartHTTPRPC ( ) )
return false ;
2015-06-27 12:21:41 -07:00
if ( GetBoolArg ( " -rest " , DEFAULT_REST_ENABLE ) & & ! StartREST ( ) )
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
return false ;
2015-11-11 08:34:10 -08:00
if ( ! StartHTTPServer ( ) )
2015-08-28 07:55:16 -07:00
return false ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
return true ;
}
2015-10-08 00:58:31 -07:00
// Parameter interaction based on rules
void InitParameterInteraction ( )
{
// when specifying an explicit binding address, you want to listen on it
// even when -connect or -proxy is specified
if ( mapArgs . count ( " -bind " ) ) {
if ( SoftSetBoolArg ( " -listen " , true ) )
LogPrintf ( " %s: parameter interaction: -bind set -> setting -listen=1 \n " , __func__ ) ;
}
if ( mapArgs . count ( " -whitebind " ) ) {
if ( SoftSetBoolArg ( " -listen " , true ) )
LogPrintf ( " %s: parameter interaction: -whitebind set -> setting -listen=1 \n " , __func__ ) ;
}
if ( mapArgs . count ( " -connect " ) & & mapMultiArgs [ " -connect " ] . size ( ) > 0 ) {
// when only connecting to trusted nodes, do not seed via DNS, or listen by default
if ( SoftSetBoolArg ( " -dnsseed " , false ) )
LogPrintf ( " %s: parameter interaction: -connect set -> setting -dnsseed=0 \n " , __func__ ) ;
if ( SoftSetBoolArg ( " -listen " , false ) )
LogPrintf ( " %s: parameter interaction: -connect set -> setting -listen=0 \n " , __func__ ) ;
}
if ( mapArgs . count ( " -proxy " ) ) {
// to protect privacy, do not listen by default if a default proxy server is specified
if ( SoftSetBoolArg ( " -listen " , false ) )
LogPrintf ( " %s: parameter interaction: -proxy set -> setting -listen=0 \n " , __func__ ) ;
// to protect privacy, do not discover addresses by default
if ( SoftSetBoolArg ( " -discover " , false ) )
LogPrintf ( " %s: parameter interaction: -proxy set -> setting -discover=0 \n " , __func__ ) ;
}
if ( ! GetBoolArg ( " -listen " , DEFAULT_LISTEN ) ) {
// do not try to retrieve public IP when not listening (pointless)
if ( SoftSetBoolArg ( " -discover " , false ) )
LogPrintf ( " %s: parameter interaction: -listen=0 -> setting -discover=0 \n " , __func__ ) ;
if ( SoftSetBoolArg ( " -listenonion " , false ) )
LogPrintf ( " %s: parameter interaction: -listen=0 -> setting -listenonion=0 \n " , __func__ ) ;
}
if ( mapArgs . count ( " -externalip " ) ) {
// if an explicit public IP is specified, do not try to find others
if ( SoftSetBoolArg ( " -discover " , false ) )
LogPrintf ( " %s: parameter interaction: -externalip set -> setting -discover=0 \n " , __func__ ) ;
}
if ( GetBoolArg ( " -salvagewallet " , false ) ) {
// Rewrite just private keys: rescan to find transactions
if ( SoftSetBoolArg ( " -rescan " , true ) )
LogPrintf ( " %s: parameter interaction: -salvagewallet=1 -> setting -rescan=1 \n " , __func__ ) ;
}
if ( GetBoolArg ( " -zapwallettxes " , false ) ) {
if ( SoftSetBoolArg ( " -rescan " , true ) )
LogPrintf ( " %s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1 \n " , __func__ ) ;
}
2015-10-08 01:01:29 -07:00
2016-01-31 03:59:18 -08:00
// disable walletbroadcast and whitelistrelay in blocksonly mode
2015-10-08 01:01:29 -07:00
if ( GetBoolArg ( " -blocksonly " , DEFAULT_BLOCKSONLY ) ) {
2015-11-25 15:00:23 -08:00
if ( SoftSetBoolArg ( " -whitelistrelay " , false ) )
LogPrintf ( " %s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0 \n " , __func__ ) ;
2015-10-08 01:01:29 -07:00
# ifdef ENABLE_WALLET
if ( SoftSetBoolArg ( " -walletbroadcast " , false ) )
LogPrintf ( " %s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0 \n " , __func__ ) ;
# endif
}
2015-11-25 15:00:23 -08:00
// Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
if ( GetBoolArg ( " -whitelistforcerelay " , DEFAULT_WHITELISTFORCERELAY ) ) {
if ( SoftSetBoolArg ( " -whitelistrelay " , true ) )
LogPrintf ( " %s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1 \n " , __func__ ) ;
}
2015-10-08 00:58:31 -07:00
}
2015-11-26 05:03:27 -08:00
void InitLogging ( )
{
fPrintToConsole = GetBoolArg ( " -printtoconsole " , false ) ;
2015-11-09 10:16:38 -08:00
fLogTimestamps = GetBoolArg ( " -logtimestamps " , DEFAULT_LOGTIMESTAMPS ) ;
fLogIPs = GetBoolArg ( " -logips " , DEFAULT_LOGIPS ) ;
2015-11-26 05:03:27 -08:00
2020-07-10 16:35:27 -07:00
// Set up the initial filtering directive from the -debug flags.
std : : string initialFilter = LogConfigFilter ( ) ;
2017-03-01 08:05:50 -08:00
fs : : path pathDebug = GetDebugLogPath ( ) ;
const fs : : path : : string_type & pathDebugStr = pathDebug . native ( ) ;
static_assert ( sizeof ( fs : : path : : value_type ) = = sizeof ( codeunit ) ,
2020-08-11 05:56:59 -07:00
" native path has unexpected code unit size " ) ;
const codeunit * pathDebugCStr = nullptr ;
size_t pathDebugLen = 0 ;
if ( ! fPrintToConsole ) {
pathDebugCStr = reinterpret_cast < const codeunit * > ( pathDebugStr . c_str ( ) ) ;
pathDebugLen = pathDebugStr . length ( ) ;
}
pTracingHandle = tracing_init (
pathDebugCStr , pathDebugLen ,
initialFilter . c_str ( ) ,
fLogTimestamps ) ;
2020-07-10 05:51:40 -07:00
2015-11-26 05:03:27 -08:00
LogPrintf ( " \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n " ) ;
LogPrintf ( " Zcash version %s (%s) \n " , FormatFullVersion ( ) , CLIENT_DATE ) ;
}
2020-07-16 23:31:42 -07:00
[[noreturn]] static void new_handler_terminate ( )
{
// Rather than throwing std::bad-alloc if allocation fails, terminate
// immediately to (try to) avoid chain corruption.
// Since LogPrintf may itself allocate memory, set the handler directly
// to terminate first.
std : : set_new_handler ( std : : terminate ) ;
fputs ( " Error: Out of memory. Terminating. \n " , stderr ) ;
LogPrintf ( " Error: Out of memory. Terminating. \n " ) ;
// The log was successful, terminate now.
std : : terminate ( ) ;
} ;
2012-05-13 02:36:10 -07:00
/** Initialize bitcoin.
* @ pre Parameters should be parsed and config file should be read .
*/
2015-04-03 08:50:06 -07:00
bool AppInit2 ( boost : : thread_group & threadGroup , CScheduler & scheduler )
2011-05-14 11:10:21 -07:00
{
2012-05-21 07:47:29 -07:00
// ********************************************************* Step 1: setup
2011-05-14 11:10:21 -07:00
# ifdef _MSC_VER
2012-07-25 17:48:39 -07:00
// Turn off Microsoft heap dump noise
2011-05-14 11:10:21 -07:00
_CrtSetReportMode ( _CRT_WARN , _CRTDBG_MODE_FILE ) ;
_CrtSetReportFile ( _CRT_WARN , CreateFileA ( " NUL " , GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , 0 , 0 ) ) ;
# endif
# if _MSC_VER >= 1400
2012-07-25 17:48:39 -07:00
// Disable confusing "helpful" text message on abort, Ctrl-C
2011-05-14 11:10:21 -07:00
_set_abort_behavior ( 0 , _WRITE_ABORT_MSG | _CALL_REPORTFAULT ) ;
# endif
2012-07-19 23:45:49 -07:00
# ifdef WIN32
// Enable Data Execution Prevention (DEP)
2019-01-23 05:37:44 -08:00
SetProcessDEPPolicy ( PROCESS_DEP_ENABLE ) ;
2011-05-14 11:10:21 -07:00
# endif
2014-06-04 04:16:07 -07:00
2015-09-02 07:18:16 -07:00
if ( ! SetupNetworking ( ) )
2019-10-21 09:13:59 -07:00
return InitError ( " Initializing networking failed " ) ;
2015-09-02 07:18:16 -07:00
# ifndef WIN32
2014-06-04 04:16:07 -07:00
if ( GetBoolArg ( " -sysperms " , false ) ) {
# ifdef ENABLE_WALLET
if ( ! GetBoolArg ( " -disablewallet " , false ) )
2019-10-21 09:13:59 -07:00
return InitError ( " -sysperms is not allowed in combination with enabled wallet functionality " ) ;
2014-06-04 04:16:07 -07:00
# endif
} else {
umask ( 077 ) ;
}
2012-07-19 23:45:49 -07:00
2011-05-14 11:10:21 -07:00
// Clean shutdown on SIGTERM
2020-03-08 03:38:49 -07:00
assert ( fRequestShutdown . is_lock_free ( ) ) ;
2011-05-14 11:10:21 -07:00
struct sigaction sa ;
sa . sa_handler = HandleSIGTERM ;
sigemptyset ( & sa . sa_mask ) ;
2020-03-28 12:14:48 -07:00
sa . sa_flags = SA_RESTART ;
2011-05-14 11:10:21 -07:00
sigaction ( SIGTERM , & sa , NULL ) ;
sigaction ( SIGINT , & sa , NULL ) ;
2012-03-02 11:31:16 -08:00
// Reopen debug.log on SIGHUP
2020-03-08 03:38:49 -07:00
assert ( fReopenDebugLog . is_lock_free ( ) ) ;
2012-03-02 11:31:16 -08:00
struct sigaction sa_hup ;
sa_hup . sa_handler = HandleSIGHUP ;
sigemptyset ( & sa_hup . sa_mask ) ;
2020-03-28 12:14:48 -07:00
sa_hup . sa_flags = SA_RESTART ;
2012-03-02 11:31:16 -08:00
sigaction ( SIGHUP , & sa_hup , NULL ) ;
2013-05-04 22:37:03 -07:00
2015-09-14 16:39:12 -07:00
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
2013-05-04 22:37:03 -07:00
signal ( SIGPIPE , SIG_IGN ) ;
2011-05-14 11:10:21 -07:00
# endif
2017-02-24 15:20:03 -08:00
std : : set_new_handler ( new_handler_terminate ) ;
2012-05-21 07:47:29 -07:00
// ********************************************************* Step 2: parameter interactions
2015-04-09 06:58:34 -07:00
const CChainParams & chainparams = Params ( ) ;
2014-11-13 06:15:53 -08:00
2015-11-28 13:28:21 -08:00
// also see: InitParameterInteraction()
2017-01-31 14:28:33 -08:00
// Set this early so that experimental features are correctly enabled/disabled
2020-01-27 06:59:24 -08:00
auto err = InitExperimentalMode ( ) ;
if ( err ) {
2020-10-20 16:39:23 -07:00
return InitError ( err . value ( ) ) ;
2012-05-24 10:02:21 -07:00
}
2021-09-21 10:45:59 -07:00
// Just temporarily (until fully functional), don't allow the Orchard wallet
// extensions if we're on mainnet
if ( fExperimentalOrchardWallet & & chainparams . NetworkIDString ( ) = = " main " ) {
return InitError ( _ ( " The -orchardwallet setting is not yet available on mainnet. " ) ) ;
}
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
// if using block pruning, then disable txindex
if ( GetArg ( " -prune " , 0 ) ) {
2015-06-27 12:21:41 -07:00
if ( GetBoolArg ( " -txindex " , DEFAULT_TXINDEX ) )
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
return InitError ( _ ( " Prune mode is incompatible with -txindex. " ) ) ;
# ifdef ENABLE_WALLET
2015-04-24 12:31:46 -07:00
if ( GetBoolArg ( " -rescan " , false ) ) {
return InitError ( _ ( " Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. " ) ) ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
}
# endif
}
2015-11-14 04:46:23 -08:00
2014-11-16 03:19:23 -08:00
// Make sure enough file descriptors are available
int nBind = std : : max ( ( int ) mapArgs . count ( " -bind " ) + ( int ) mapArgs . count ( " -whitebind " ) , 1 ) ;
int nUserMaxConnections = GetArg ( " -maxconnections " , DEFAULT_MAX_PEER_CONNECTIONS ) ;
nMaxConnections = std : : max ( nUserMaxConnections , 0 ) ;
// Trim requested connection counts, to fit into system limitations
nMaxConnections = std : : max ( std : : min ( nMaxConnections , FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS ) , 0 ) ;
int nFD = RaiseFileDescriptorLimit ( nMaxConnections + MIN_CORE_FILEDESCRIPTORS ) ;
if ( nFD < MIN_CORE_FILEDESCRIPTORS )
return InitError ( _ ( " Not enough file descriptors available. " ) ) ;
nMaxConnections = std : : min ( nFD - MIN_CORE_FILEDESCRIPTORS , nMaxConnections ) ;
if ( nMaxConnections < nUserMaxConnections )
InitWarning ( strprintf ( _ ( " Reducing -maxconnections from %d to %d, because of system limitations. " ) , nUserMaxConnections , nMaxConnections ) ) ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
2020-10-09 10:54:06 -07:00
// ensure that the user has not disabled checkpoints when requesting to
// skip transaction verification in initial block download.
if ( GetBoolArg ( " -ibdskiptxverification " , DEFAULT_IBD_SKIP_TX_VERIFICATION ) ) {
if ( ! GetBoolArg ( " -checkpoints " , DEFAULT_CHECKPOINTS_ENABLED ) ) {
2020-10-12 14:38:07 -07:00
return InitError ( _ ( " -ibdskiptxverification requires checkpoints to be enabled; it is incompatible with flags that disable checkpoints " ) ) ;
2020-10-09 10:54:06 -07:00
}
}
2012-05-21 07:47:29 -07:00
// ********************************************************* Step 3: parameter-to-internal-flags
2013-10-08 03:09:40 -07:00
fDebug = ! mapMultiArgs [ " -debug " ] . empty ( ) ;
// Special-case: if -debug=0/-nodebug is set, turn off debugging messages
2017-01-27 00:43:41 -08:00
const std : : vector < std : : string > & categories = mapMultiArgs [ " -debug " ] ;
if ( GetBoolArg ( " -nodebug " , false ) | | find ( categories . begin ( ) , categories . end ( ) , std : : string ( " 0 " ) ) ! = categories . end ( ) )
2013-10-08 03:09:40 -07:00
fDebug = false ;
2017-02-06 23:29:07 -08:00
// Special case: if debug=zrpcunsafe, implies debug=zrpc, so add it to debug categories
2017-01-27 00:43:41 -08:00
if ( find ( categories . begin ( ) , categories . end ( ) , std : : string ( " zrpcunsafe " ) ) ! = categories . end ( ) ) {
if ( find ( categories . begin ( ) , categories . end ( ) , std : : string ( " zrpc " ) ) = = categories . end ( ) ) {
2017-02-07 00:02:02 -08:00
LogPrintf ( " %s: parameter interaction: setting -debug=zrpcunsafe -> -debug=zrpc \n " , __func__ ) ;
2017-01-27 00:43:41 -08:00
std : : vector < std : : string > & v = mapMultiArgs [ " -debug " ] ;
2017-02-06 23:29:07 -08:00
v . push_back ( " zrpc " ) ;
}
}
2014-06-27 05:41:11 -07:00
// Check for -debugnet
2013-10-08 03:09:40 -07:00
if ( GetBoolArg ( " -debugnet " , false ) )
2019-10-21 09:13:59 -07:00
InitWarning ( _ ( " Unsupported argument -debugnet ignored, use -debug=net. " ) ) ;
2014-06-15 23:48:32 -07:00
// Check for -socks - as this is a privacy risk to continue, exit here
if ( mapArgs . count ( " -socks " ) )
2019-10-21 09:13:59 -07:00
return InitError ( _ ( " Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. " ) ) ;
2014-05-05 11:32:56 -07:00
// Check for -tor - as this is a privacy risk to continue, exit here
if ( GetBoolArg ( " -tor " , false ) )
2019-10-21 09:13:59 -07:00
return InitError ( _ ( " Unsupported argument -tor found, use -onion. " ) ) ;
2013-10-08 03:09:40 -07:00
2014-07-26 13:49:17 -07:00
if ( GetBoolArg ( " -benchmark " , false ) )
2019-10-21 09:13:59 -07:00
InitWarning ( _ ( " Unsupported argument -benchmark ignored, use -debug=bench. " ) ) ;
2014-07-26 13:49:17 -07:00
2015-03-13 09:25:34 -07:00
// Checkmempool and checkblockindex default to true in regtest mode
2015-10-07 14:34:55 -07:00
int ratio = std : : min < int > ( std : : max < int > ( GetArg ( " -checkmempool " , chainparams . DefaultConsistencyChecks ( ) ? 1 : 0 ) , 0 ) , 1000000 ) ;
if ( ratio ! = 0 ) {
mempool . setSanityCheck ( 1.0 / ratio ) ;
}
2019-09-26 08:22:25 -07:00
2019-10-21 08:20:17 -07:00
int64_t mempoolTotalCostLimit = GetArg ( " -mempooltxcostlimit " , DEFAULT_MEMPOOL_TOTAL_COST_LIMIT ) ;
int64_t mempoolEvictionMemorySeconds = GetArg ( " -mempoolevictionmemoryminutes " , DEFAULT_MEMPOOL_EVICTION_MEMORY_MINUTES ) * 60 ;
2019-10-07 13:23:06 -07:00
mempool . SetMempoolCostLimit ( mempoolTotalCostLimit , mempoolEvictionMemorySeconds ) ;
2019-09-26 08:22:25 -07:00
2015-04-09 06:58:34 -07:00
fCheckBlockIndex = GetBoolArg ( " -checkblockindex " , chainparams . DefaultConsistencyChecks ( ) ) ;
2020-10-09 08:45:31 -07:00
fIBDSkipTxVerification = GetBoolArg ( " -ibdskiptxverification " , DEFAULT_IBD_SKIP_TX_VERIFICATION ) ;
2015-11-09 10:16:38 -08:00
fCheckpointsEnabled = GetBoolArg ( " -checkpoints " , DEFAULT_CHECKPOINTS_ENABLED ) ;
2012-06-22 10:11:57 -07:00
2012-12-01 14:04:14 -08:00
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
2014-02-18 03:48:16 -08:00
nScriptCheckThreads = GetArg ( " -par " , DEFAULT_SCRIPTCHECK_THREADS ) ;
2013-04-29 10:35:47 -07:00
if ( nScriptCheckThreads < = 0 )
2015-07-01 08:38:15 -07:00
nScriptCheckThreads + = GetNumCores ( ) ;
2013-01-18 06:07:05 -08:00
if ( nScriptCheckThreads < = 1 )
2012-12-01 14:04:14 -08:00
nScriptCheckThreads = 0 ;
else if ( nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS )
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS ;
2013-12-20 02:48:22 -08:00
fServer = GetBoolArg ( " -server " , false ) ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
2015-09-11 14:31:30 -07:00
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
int64_t nSignedPruneTarget = GetArg ( " -prune " , 0 ) * 1024 * 1024 ;
if ( nSignedPruneTarget < 0 ) {
return InitError ( _ ( " Prune cannot be configured with a negative value. " ) ) ;
}
nPruneTarget = ( uint64_t ) nSignedPruneTarget ;
if ( nPruneTarget ) {
if ( nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES ) {
2015-09-11 14:31:30 -07:00
return InitError ( strprintf ( _ ( " Prune configured below the minimum of %d MiB. Please use a higher number. " ) , MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024 ) ) ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
}
LogPrintf ( " Prune configured to target %uMiB on disk for block and undo files. \n " , nPruneTarget / 1024 / 1024 ) ;
fPruneMode = true ;
}
2016-03-29 10:43:02 -07:00
RegisterAllCoreRPCCommands ( tableRPC ) ;
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2013-10-02 08:19:10 -07:00
bool fDisableWallet = GetBoolArg ( " -disablewallet " , false ) ;
2016-01-06 23:33:49 -08:00
if ( ! fDisableWallet )
2016-03-29 10:43:02 -07:00
RegisterWalletRPCCommands ( tableRPC ) ;
2013-11-29 07:04:29 -08:00
# endif
2011-05-14 11:10:21 -07:00
2014-09-25 00:01:54 -07:00
nConnectTimeout = GetArg ( " -timeout " , DEFAULT_CONNECT_TIMEOUT ) ;
if ( nConnectTimeout < = 0 )
nConnectTimeout = DEFAULT_CONNECT_TIMEOUT ;
2012-05-21 07:47:29 -07:00
2013-04-25 17:11:27 -07:00
// Fee-per-kilobyte amount considered the same as "free"
// If you are mining, be careful setting this:
// if you set it to zero then
// a transaction spammer can cheaply fill blocks using
// 1-satoshi-fee transactions. It should be set above the real
// cost to you of processing a transaction.
if ( mapArgs . count ( " -minrelaytxfee " ) )
{
2014-04-22 15:46:19 -07:00
CAmount n = 0 ;
2013-04-25 17:11:27 -07:00
if ( ParseMoney ( mapArgs [ " -minrelaytxfee " ] , n ) & & n > 0 )
2014-07-03 11:25:32 -07:00
: : minRelayTxFee = CFeeRate ( n ) ;
2013-04-25 17:11:27 -07:00
else
2014-01-16 07:15:27 -08:00
return InitError ( strprintf ( _ ( " Invalid amount for -minrelaytxfee=<amount>: '%s' " ) , mapArgs [ " -minrelaytxfee " ] ) ) ;
2013-04-25 17:11:27 -07:00
}
2012-05-21 07:47:29 -07:00
2013-12-13 07:14:48 -08:00
# ifdef ENABLE_WALLET
2021-09-21 12:23:47 -07:00
if ( ! CWallet : : ParameterInteraction ( chainparams ) )
2016-03-15 02:30:37 -07:00
return false ;
2014-07-16 17:04:04 -07:00
# endif // ENABLE_WALLET
2015-11-09 10:16:38 -08:00
fIsBareMultisigStd = GetBoolArg ( " -permitbaremultisig " , DEFAULT_PERMIT_BAREMULTISIG ) ;
fAcceptDatacarrier = GetBoolArg ( " -datacarrier " , DEFAULT_ACCEPT_DATACARRIER ) ;
2014-10-10 16:55:14 -07:00
nMaxDatacarrierBytes = GetArg ( " -datacarriersize " , nMaxDatacarrierBytes ) ;
2014-07-16 17:04:04 -07:00
2015-06-12 03:00:39 -07:00
fAlerts = GetBoolArg ( " -alerts " , DEFAULT_ALERTS ) ;
2015-06-19 07:42:39 -07:00
// Option to startup with mocktime set (used for regression testing):
SetMockTime ( GetArg ( " -mocktime " , 0 ) ) ; // SetMockTime(0) is a no-op
2016-02-10 22:35:25 -08:00
if ( GetBoolArg ( " -peerbloomfilters " , DEFAULT_PEERBLOOMFILTERS ) )
2015-08-20 21:15:27 -07:00
nLocalServices | = NODE_BLOOM ;
2015-12-14 04:23:45 -08:00
nMaxTipAge = GetArg ( " -maxtipage " , DEFAULT_MAX_TIP_AGE ) ;
2020-07-09 15:53:54 -07:00
KeyIO keyIO ( chainparams ) ;
2016-12-22 20:30:27 -08:00
# ifdef ENABLE_MINING
if ( mapArgs . count ( " -mineraddress " ) ) {
2021-12-29 12:44:55 -08:00
auto addr = keyIO . DecodePaymentAddress ( mapArgs [ " -mineraddress " ] ) ;
if ( ! ( addr . has_value ( ) & & std : : visit ( ExtractMinerAddress ( ) , addr . value ( ) ) . has_value ( ) ) ) {
return InitError ( strprintf (
2022-01-10 18:41:26 -08:00
_ ( " Invalid address for -mineraddress=<addr>: '%s' (must be a Sapling or transparent P2PKH address) " ) ,
2021-12-29 12:44:55 -08:00
mapArgs [ " -mineraddress " ] ) ) ;
2016-12-22 20:30:27 -08:00
}
}
# endif
2018-01-31 12:11:18 -08:00
if ( ! mapMultiArgs [ " -nuparams " ] . empty ( ) ) {
// Allow overriding network upgrade parameters for testing
2020-07-10 10:34:53 -07:00
if ( chainparams . NetworkIDString ( ) ! = " regtest " ) {
2018-01-31 12:11:18 -08:00
return InitError ( " Network upgrade parameters may only be overridden on regtest. " ) ;
}
2017-01-27 00:43:41 -08:00
const std : : vector < std : : string > & deployments = mapMultiArgs [ " -nuparams " ] ;
2018-01-31 12:11:18 -08:00
for ( auto i : deployments ) {
std : : vector < std : : string > vDeploymentParams ;
boost : : split ( vDeploymentParams , i , boost : : is_any_of ( " : " ) ) ;
if ( vDeploymentParams . size ( ) ! = 2 ) {
return InitError ( " Network upgrade parameters malformed, expecting hexBranchId:activationHeight " ) ;
}
int nActivationHeight ;
if ( ! ParseInt32 ( vDeploymentParams [ 1 ] , & nActivationHeight ) ) {
return InitError ( strprintf ( " Invalid nActivationHeight (%s) " , vDeploymentParams[1])) ;
}
bool found = false ;
// Exclude Sprout from upgrades
for ( auto i = Consensus : : BASE_SPROUT + 1 ; i < Consensus : : MAX_NETWORK_UPGRADES ; + + i )
{
if ( vDeploymentParams [ 0 ] . compare ( HexInt ( NetworkUpgradeInfo [ i ] . nBranchId ) ) = = 0 ) {
UpdateNetworkUpgradeParameters ( Consensus : : UpgradeIndex ( i ) , nActivationHeight ) ;
found = true ;
LogPrintf ( " Setting network upgrade activation parameters for %s to height=%d \n " , vDeploymentParams [ 0 ] , nActivationHeight ) ;
break ;
}
}
if ( ! found ) {
return InitError ( strprintf ( " Invalid network upgrade (%s) " , vDeploymentParams[0])) ;
}
}
2021-12-03 12:32:40 -08:00
// To make testing easier (this code path is active only for regtest), activate missing network versions,
// so for example, if a Python (RPC) test does:
// extra_args = [
// nuparams(BLOSSOM_BRANCH_ID, 205),
// nuparams(HEARTWOOD_BRANCH_ID, 205),
// nuparams(CANOPY_BRANCH_ID, 205),
// nuparams(NU5_BRANCH_ID, 210),
// ]
//
// This can be simplified to:
// extra_args = [
// nuparams(CANOPY_BRANCH_ID, 205),
// nuparams(NU5_BRANCH_ID, 210),
// ]
const auto & consensus = chainparams . GetConsensus ( ) ;
int nActivationHeight = Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ;
for ( auto i = Consensus : : MAX_NETWORK_UPGRADES - 1 ; i > = Consensus : : BASE_SPROUT + 1 ; - - i ) {
if ( consensus . vUpgrades [ i ] . nActivationHeight = = Consensus : : NetworkUpgrade : : NO_ACTIVATION_HEIGHT ) {
UpdateNetworkUpgradeParameters ( Consensus : : UpgradeIndex ( i ) , nActivationHeight ) ;
}
nActivationHeight = consensus . vUpgrades [ i ] . nActivationHeight ;
}
2018-01-31 12:11:18 -08:00
}
2017-05-04 11:35:08 -07:00
2019-12-13 09:24:56 -08:00
if ( mapArgs . count ( " -nurejectoldversions " ) ) {
2020-07-10 10:34:53 -07:00
if ( chainparams . NetworkIDString ( ) ! = " regtest " ) {
2019-12-13 09:24:56 -08:00
return InitError ( " -nurejectoldversions may only be set on regtest. " ) ;
}
}
2020-06-05 14:46:45 -07:00
if ( ! mapMultiArgs [ " -fundingstream " ] . empty ( ) ) {
// Allow overriding network upgrade parameters for testing
2020-07-10 10:34:53 -07:00
if ( chainparams . NetworkIDString ( ) ! = " regtest " ) {
2020-06-05 14:46:45 -07:00
return InitError ( " Funding stream parameters may only be overridden on regtest. " ) ;
}
2020-07-01 15:06:27 -07:00
const std : : vector < std : : string > & streams = mapMultiArgs [ " -fundingstream " ] ;
2020-06-05 14:46:45 -07:00
for ( auto i : streams ) {
std : : vector < std : : string > vStreamParams ;
boost : : split ( vStreamParams , i , boost : : is_any_of ( " : " ) ) ;
if ( vStreamParams . size ( ) ! = 4 ) {
return InitError ( " Funding stream parameters malformed, expecting streamId:startHeight:endHeight:comma_delimited_addresses " ) ;
}
int nFundingStreamId ;
2020-10-09 08:45:31 -07:00
if ( ! ParseInt32 ( vStreamParams [ 0 ] , & nFundingStreamId ) | |
nFundingStreamId < Consensus : : FIRST_FUNDING_STREAM | |
2020-06-05 14:46:45 -07:00
nFundingStreamId > = Consensus : : MAX_FUNDING_STREAMS ) {
return InitError ( strprintf ( " Invalid streamId (%s) " , vStreamParams[0])) ;
}
int nStartHeight ;
if ( ! ParseInt32 ( vStreamParams [ 1 ] , & nStartHeight ) ) {
return InitError ( strprintf ( " Invalid funding stream start height (%s) " , vStreamParams[1])) ;
}
int nEndHeight ;
if ( ! ParseInt32 ( vStreamParams [ 2 ] , & nEndHeight ) ) {
return InitError ( strprintf ( " Invalid funding stream end height (%s) " , vStreamParams[2])) ;
}
std : : vector < std : : string > vStreamAddrs ;
boost : : split ( vStreamAddrs , vStreamParams [ 3 ] , boost : : is_any_of ( " , " ) ) ;
2020-07-09 15:53:54 -07:00
auto fs = Consensus : : FundingStream : : ParseFundingStream (
2020-07-10 10:34:53 -07:00
chainparams . GetConsensus ( ) , chainparams , nStartHeight , nEndHeight , vStreamAddrs ) ;
2020-06-05 14:46:45 -07:00
UpdateFundingStreamParameters ( ( Consensus : : FundingStreamIndex ) nFundingStreamId , fs ) ;
}
}
2012-05-21 07:47:29 -07:00
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
2014-09-25 00:03:30 -07:00
2016-07-10 20:10:02 -07:00
// Initialize libsodium
2020-12-17 03:31:40 -08:00
if ( sodium_init ( ) = = - 1 ) {
2016-07-10 20:10:02 -07:00
return false ;
}
Update key.cpp to use new libsecp256k1
libsecp256k1's API changed, so update key.cpp to use it.
Libsecp256k1 now has explicit context objects, which makes it completely thread-safe.
In turn, keep an explicit context object in key.cpp, which is explicitly initialized
destroyed. This is not really pretty now, but it's more efficient than the static
initialized object in key.cpp (which made for example bitcoin-tx slow, as for most of
its calls, libsecp256k1 wasn't actually needed).
This also brings in the new blinding support in libsecp256k1. By passing in a random
seed, temporary variables during the elliptic curve computations are altered, in such
a way that if an attacker does not know the blind, observing the internal operations
leaks less information about the keys used. This was implemented by Greg Maxwell.
2015-04-22 14:28:26 -07:00
// Initialize elliptic curve code
ECC_Start ( ) ;
2015-07-28 11:11:20 -07:00
globalVerifyHandle . reset ( new ECCVerifyHandle ( ) ) ;
Update key.cpp to use new libsecp256k1
libsecp256k1's API changed, so update key.cpp to use it.
Libsecp256k1 now has explicit context objects, which makes it completely thread-safe.
In turn, keep an explicit context object in key.cpp, which is explicitly initialized
destroyed. This is not really pretty now, but it's more efficient than the static
initialized object in key.cpp (which made for example bitcoin-tx slow, as for most of
its calls, libsecp256k1 wasn't actually needed).
This also brings in the new blinding support in libsecp256k1. By passing in a random
seed, temporary variables during the elliptic curve computations are altered, in such
a way that if an attacker does not know the blind, observing the internal operations
leaks less information about the keys used. This was implemented by Greg Maxwell.
2015-04-22 14:28:26 -07:00
2014-06-02 16:21:03 -07:00
// Sanity check
if ( ! InitSanityCheck ( ) )
2016-10-26 12:57:22 -07:00
return InitError ( _ ( " Initialization sanity check failed. Zcash is shutting down. " ) ) ;
2012-05-21 07:47:29 -07:00
2012-10-11 18:09:05 -07:00
std : : string strDataDir = GetDataDir ( ) . string ( ) ;
2016-03-15 02:30:37 -07:00
2012-05-21 07:47:29 -07:00
// Make sure only a single Bitcoin process is using the data directory.
2017-03-01 08:05:50 -08:00
fs : : path pathLockFile = GetDataDir ( ) / " .lock " ;
2017-03-01 08:28:39 -08:00
FILE * file = fsbridge : : fopen ( pathLockFile , " a " ) ; // empty lock file; created if it doesn't exist.
2012-05-21 07:47:29 -07:00
if ( file ) fclose ( file ) ;
2015-05-18 16:37:43 -07:00
try {
static boost : : interprocess : : file_lock lock ( pathLockFile . string ( ) . c_str ( ) ) ;
if ( ! lock . try_lock ( ) )
2016-10-26 12:57:22 -07:00
return InitError ( strprintf ( _ ( " Cannot obtain a lock on data directory %s. Zcash is probably already running. " ) , strDataDir ) ) ;
2015-05-18 16:37:43 -07:00
} catch ( const boost : : interprocess : : interprocess_exception & e ) {
2016-10-26 12:57:22 -07:00
return InitError ( strprintf ( _ ( " Cannot obtain a lock on data directory %s. Zcash is probably already running. " ) + " %s. " , strDataDir , e . what ( ) ) ) ;
2015-05-18 16:37:43 -07:00
}
2014-09-20 01:56:25 -07:00
# ifndef WIN32
CreatePidFile ( GetPidFile ( ) , getpid ( ) ) ;
# endif
2019-09-19 10:05:56 -07:00
// if (GetBoolArg("-shrinkdebugfile", !fDebug))
// ShrinkDebugFile();
2015-05-15 12:31:14 -07:00
2014-05-01 00:44:45 -07:00
# ifdef ENABLE_WALLET
LogPrintf ( " Using BerkeleyDB version %s \n " , DbEnv : : version ( 0 , 0 , 0 ) ) ;
# endif
2012-09-04 09:24:08 -07:00
if ( ! fLogTimestamps )
2014-01-16 07:15:27 -08:00
LogPrintf ( " Startup time: %s \n " , DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , GetTime ( ) ) ) ;
LogPrintf ( " Default data directory %s \n " , GetDefaultDataDir ( ) . string ( ) ) ;
LogPrintf ( " Using data directory %s \n " , strDataDir ) ;
2016-09-28 01:10:15 -07:00
LogPrintf ( " Using config file %s \n " , GetConfigFile ( GetArg ( " -conf " , BITCOIN_CONF_FILENAME ) ) . string ( ) ) ;
2013-09-18 03:38:08 -07:00
LogPrintf ( " Using at most %i connections (%i file descriptors available) \n " , nMaxConnections , nFD ) ;
2012-05-21 07:47:29 -07:00
std : : ostringstream strErrors ;
2011-05-14 11:10:21 -07:00
2014-11-05 23:47:48 -08:00
LogPrintf ( " Using %u threads for script verification \n " , nScriptCheckThreads ) ;
2012-12-01 14:04:14 -08:00
if ( nScriptCheckThreads ) {
for ( int i = 0 ; i < nScriptCheckThreads - 1 ; i + + )
2013-03-06 19:31:26 -08:00
threadGroup . create_thread ( & ThreadScriptCheck ) ;
2012-12-01 14:04:14 -08:00
}
2015-04-03 08:50:06 -07:00
// Start the lightweight task scheduler thread
CScheduler : : Function serviceLoop = boost : : bind ( & CScheduler : : serviceQueue , & scheduler ) ;
threadGroup . create_thread ( boost : : bind ( & TraceThread < CScheduler : : Function > , " scheduler " , serviceLoop ) ) ;
2016-10-25 13:11:41 -07:00
// Count uptime
MarkStartTime ( ) ;
2021-01-06 21:30:28 -08:00
int prometheusPort = GetArg ( " -prometheusport " , - 1 ) ;
if ( prometheusPort > 0 ) {
const std : : vector < std : : string > & vAllow = mapMultiArgs [ " -metricsallowip " ] ;
std : : vector < const char * > vAllowCstr ;
for ( const std : : string & strAllow : vAllow ) {
vAllowCstr . push_back ( strAllow . c_str ( ) ) ;
}
std : : string metricsBind = GetArg ( " -metricsbind " , " " ) ;
const char * metricsBindCstr = nullptr ;
if ( ! metricsBind . empty ( ) ) {
metricsBindCstr = metricsBind . c_str ( ) ;
}
2020-10-16 16:54:04 -07:00
// Start up the metrics runtime. This spins off a Rust thread that runs
2021-01-06 07:49:14 -08:00
// the Prometheus exporter. We just let this thread die at process end.
2020-10-16 16:54:04 -07:00
LogPrintf ( " metrics thread start " ) ;
2021-01-06 21:30:28 -08:00
if ( ! metrics_run ( metricsBindCstr , vAllowCstr . data ( ) , vAllowCstr . size ( ) , prometheusPort ) ) {
return InitError ( strprintf ( _ ( " Failed to start Prometheus metrics exporter " ) ) ) ;
2020-10-16 16:54:04 -07:00
}
}
2020-12-24 08:33:44 -08:00
// Expose binary metadata to metrics, using a single time series with value 1.
// https://www.robustperception.io/exposing-the-software-version-to-prometheus
MetricsIncrementCounter (
" zcashd.build.info " ,
" version " , CLIENT_BUILD . c_str ( ) ) ;
2016-10-27 19:35:49 -07:00
if ( ( chainparams . NetworkIDString ( ) ! = " regtest " ) & &
2016-11-17 19:37:10 -08:00
GetBoolArg ( " -showmetrics " , isatty ( STDOUT_FILENO ) ) & &
2016-10-27 19:35:49 -07:00
! fPrintToConsole & & ! GetBoolArg ( " -daemon " , false ) ) {
2016-09-03 09:39:45 -07:00
// Start the persistent metrics interface
2016-09-03 10:51:54 -07:00
ConnectMetricsScreen ( ) ;
2016-09-03 09:39:45 -07:00
threadGroup . create_thread ( & ThreadShowMetricsScreen ) ;
}
2016-11-02 11:03:41 -07:00
// Initialize Zcash circuit parameters
2018-04-17 13:44:53 -07:00
ZC_LoadParams ( chainparams ) ;
2016-11-02 11:03:41 -07:00
2014-10-29 10:08:31 -07:00
/* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already ( but it will signify connections
* that the server is there and will be ready later ) . Warmup mode will
* be disabled when initialisation is finished .
*/
if ( fServer )
{
uiInterface . InitMessage . connect ( SetRPCWarmupStatus ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
if ( ! AppInitServers ( threadGroup ) )
return InitError ( _ ( " Unable to start HTTP server. See debug log for details. " ) ) ;
2014-10-29 10:08:31 -07:00
}
2013-04-12 22:13:08 -07:00
int64_t nStart ;
2012-05-21 07:47:29 -07:00
2013-01-11 14:18:00 -08:00
// ********************************************************* Step 5: verify wallet database integrity
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2013-10-02 08:19:10 -07:00
if ( ! fDisableWallet ) {
2016-03-15 02:30:37 -07:00
if ( ! CWallet : : Verify ( ) )
2015-02-04 12:19:27 -08:00
return false ;
2013-10-02 08:19:10 -07:00
} // (!fDisableWallet)
2013-11-29 07:04:29 -08:00
# endif // ENABLE_WALLET
2012-09-18 11:30:47 -07:00
// ********************************************************* Step 6: network initialization
2012-05-21 07:47:29 -07:00
2013-06-05 20:21:41 -07:00
RegisterNodeSignals ( GetNodeSignals ( ) ) ;
2013-05-07 06:16:25 -07:00
2015-09-09 05:24:56 -07:00
// sanitize comments per BIP-0014, format user agent and check total size
std : : vector < string > uacomments ;
2017-01-27 00:43:41 -08:00
for ( std : : string cmt : mapMultiArgs [ " -uacomment " ] )
2015-09-09 05:24:56 -07:00
{
if ( cmt ! = SanitizeString ( cmt , SAFE_CHARS_UA_COMMENT ) )
return InitError ( strprintf ( " User Agent comment (%s) contains unsafe characters . " , cmt)) ;
uacomments . push_back ( SanitizeString ( cmt , SAFE_CHARS_UA_COMMENT ) ) ;
}
strSubVersion = FormatSubVersion ( CLIENT_NAME , CLIENT_VERSION , uacomments ) ;
2015-07-31 09:05:42 -07:00
if ( strSubVersion . size ( ) > MAX_SUBVERSION_LENGTH ) {
return InitError ( strprintf ( " Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments. " ,
strSubVersion . size ( ) , MAX_SUBVERSION_LENGTH ) ) ;
}
2012-05-21 07:47:29 -07:00
if ( mapArgs . count ( " -onlynet " ) ) {
std : : set < enum Network > nets ;
2017-06-01 18:18:57 -07:00
for ( const std : : string & snet : mapMultiArgs [ " -onlynet " ] ) {
2012-05-21 07:47:29 -07:00
enum Network net = ParseNetwork ( snet ) ;
if ( net = = NET_UNROUTABLE )
2014-01-16 07:15:27 -08:00
return InitError ( strprintf ( _ ( " Unknown network specified in -onlynet: '%s' " ) , snet ) ) ;
2012-05-21 07:47:29 -07:00
nets . insert ( net ) ;
}
for ( int n = 0 ; n < NET_MAX ; n + + ) {
enum Network net = ( enum Network ) n ;
if ( ! nets . count ( net ) )
SetLimited ( net ) ;
}
}
2014-06-21 04:34:36 -07:00
if ( mapArgs . count ( " -whitelist " ) ) {
2017-06-01 18:18:57 -07:00
for ( const std : : string & net : mapMultiArgs [ " -whitelist " ] ) {
2014-06-21 04:34:36 -07:00
CSubNet subnet ( net ) ;
if ( ! subnet . IsValid ( ) )
return InitError ( strprintf ( _ ( " Invalid netmask specified in -whitelist: '%s' " ) , net ) ) ;
CNode : : AddWhitelistedRange ( subnet ) ;
}
}
2015-06-27 12:21:41 -07:00
bool proxyRandomize = GetBoolArg ( " -proxyrandomize " , DEFAULT_PROXYRANDOMIZE ) ;
2015-06-10 00:19:13 -07:00
// -proxy sets a proxy for all outgoing network traffic
// -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
std : : string proxyArg = GetArg ( " -proxy " , " " ) ;
2016-02-17 22:44:32 -08:00
SetLimited ( NET_TOR ) ;
2015-06-10 00:19:13 -07:00
if ( proxyArg ! = " " & & proxyArg ! = " 0 " ) {
proxyType addrProxy = proxyType ( CService ( proxyArg , 9050 ) , proxyRandomize ) ;
2012-05-24 10:02:21 -07:00
if ( ! addrProxy . IsValid ( ) )
2015-06-10 00:19:13 -07:00
return InitError ( strprintf ( _ ( " Invalid -proxy address: '%s' " ) , proxyArg ) ) ;
2012-05-24 10:02:21 -07:00
2014-11-23 15:12:50 -08:00
SetProxy ( NET_IPV4 , addrProxy ) ;
SetProxy ( NET_IPV6 , addrProxy ) ;
2015-06-10 00:19:13 -07:00
SetProxy ( NET_TOR , addrProxy ) ;
2014-06-11 04:20:59 -07:00
SetNameProxy ( addrProxy ) ;
2016-02-17 22:44:32 -08:00
SetLimited ( NET_TOR , false ) ; // by default, -proxy sets onion as reachable, unless -noonion later
2012-05-01 12:04:07 -07:00
}
2015-06-10 00:19:13 -07:00
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
// -noonion (or -onion=0) disables connecting to .onion entirely
// An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none)
std : : string onionArg = GetArg ( " -onion " , " " ) ;
if ( onionArg ! = " " ) {
if ( onionArg = = " 0 " ) { // Handle -noonion/-onion=0
2016-02-17 22:44:32 -08:00
SetLimited ( NET_TOR ) ; // set onions as unreachable
2015-06-10 00:19:13 -07:00
} else {
proxyType addrOnion = proxyType ( CService ( onionArg , 9050 ) , proxyRandomize ) ;
if ( ! addrOnion . IsValid ( ) )
return InitError ( strprintf ( _ ( " Invalid -onion address: '%s' " ) , onionArg ) ) ;
SetProxy ( NET_TOR , addrOnion ) ;
2016-02-17 22:44:32 -08:00
SetLimited ( NET_TOR , false ) ;
2015-06-10 00:19:13 -07:00
}
2012-05-24 10:02:21 -07:00
}
// see Step 2: parameter interactions for more information about these
2014-05-29 04:02:22 -07:00
fListen = GetBoolArg ( " -listen " , DEFAULT_LISTEN ) ;
2012-05-24 10:02:21 -07:00
fDiscover = GetBoolArg ( " -discover " , true ) ;
2015-11-09 10:16:38 -08:00
fNameLookup = GetBoolArg ( " -dns " , DEFAULT_NAME_LOOKUP ) ;
2012-05-16 19:11:19 -07:00
2012-05-21 07:47:29 -07:00
bool fBound = false ;
2014-05-29 03:33:17 -07:00
if ( fListen ) {
2014-06-21 04:34:36 -07:00
if ( mapArgs . count ( " -bind " ) | | mapArgs . count ( " -whitebind " ) ) {
2017-06-01 18:18:57 -07:00
for ( const std : : string & strBind : mapMultiArgs [ " -bind " ] ) {
2012-05-21 07:47:29 -07:00
CService addrBind ;
if ( ! Lookup ( strBind . c_str ( ) , addrBind , GetListenPort ( ) , false ) )
2014-01-16 07:15:27 -08:00
return InitError ( strprintf ( _ ( " Cannot resolve -bind address: '%s' " ) , strBind ) ) ;
2012-09-03 06:54:47 -07:00
fBound | = Bind ( addrBind , ( BF_EXPLICIT | BF_REPORT_ERROR ) ) ;
2012-05-21 07:47:29 -07:00
}
2017-06-01 18:18:57 -07:00
for ( const std : : string & strBind : mapMultiArgs [ " -whitebind " ] ) {
2014-06-21 04:34:36 -07:00
CService addrBind ;
if ( ! Lookup ( strBind . c_str ( ) , addrBind , 0 , false ) )
return InitError ( strprintf ( _ ( " Cannot resolve -whitebind address: '%s' " ) , strBind ) ) ;
if ( addrBind . GetPort ( ) = = 0 )
return InitError ( strprintf ( _ ( " Need to specify a port with -whitebind: '%s' " ) , strBind ) ) ;
fBound | = Bind ( addrBind , ( BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST ) ) ;
}
2012-09-03 06:54:47 -07:00
}
else {
2012-05-21 07:47:29 -07:00
struct in_addr inaddr_any ;
inaddr_any . s_addr = INADDR_ANY ;
2012-09-03 06:54:47 -07:00
fBound | = Bind ( CService ( in6addr_any , GetListenPort ( ) ) , BF_NONE ) ;
fBound | = Bind ( CService ( inaddr_any , GetListenPort ( ) ) , ! fBound ? BF_REPORT_ERROR : BF_NONE ) ;
2012-05-21 07:47:29 -07:00
}
if ( ! fBound )
2012-05-24 10:02:21 -07:00
return InitError ( _ ( " Failed to listen on any port. Use -listen=0 if you want this. " ) ) ;
2012-05-16 19:11:19 -07:00
}
2012-09-03 06:54:47 -07:00
if ( mapArgs . count ( " -externalip " ) ) {
2017-06-01 18:18:57 -07:00
for ( const std : : string & strAddr : mapMultiArgs [ " -externalip " ] ) {
2012-05-21 07:47:29 -07:00
CService addrLocal ( strAddr , GetListenPort ( ) , fNameLookup ) ;
if ( ! addrLocal . IsValid ( ) )
2014-01-16 07:15:27 -08:00
return InitError ( strprintf ( _ ( " Cannot resolve -externalip address: '%s' " ) , strAddr ) ) ;
2012-05-21 07:47:29 -07:00
AddLocal ( CService ( strAddr , GetListenPort ( ) , fNameLookup ) , LOCAL_MANUAL ) ;
}
}
2017-06-01 18:18:57 -07:00
for ( const std : : string & strDest : mapMultiArgs [ " -seednode " ] )
2012-05-24 10:02:21 -07:00
AddOneShot ( strDest ) ;
2014-11-18 09:06:32 -08:00
# if ENABLE_ZMQ
pzmqNotificationInterface = CZMQNotificationInterface : : CreateWithArguments ( mapArgs ) ;
if ( pzmqNotificationInterface ) {
RegisterValidationInterface ( pzmqNotificationInterface ) ;
}
# endif
2015-09-02 08:03:27 -07:00
if ( mapArgs . count ( " -maxuploadtarget " ) ) {
2020-08-13 13:17:51 -07:00
CNode : : SetMaxOutboundTarget (
chainparams . GetConsensus ( ) . nPostBlossomPowTargetSpacing ,
GetArg ( " -maxuploadtarget " , DEFAULT_MAX_UPLOAD_TARGET ) * 1024 * 1024 ) ;
2015-09-02 08:03:27 -07:00
}
2014-11-18 09:06:32 -08:00
2012-10-05 10:22:21 -07:00
// ********************************************************* Step 7: load block chain
2012-05-21 07:47:29 -07:00
2013-04-28 08:37:50 -07:00
fReindex = GetBoolArg ( " -reindex " , false ) ;
2016-04-21 05:14:37 -07:00
bool fReindexChainState = GetBoolArg ( " -reindex-chainstate " , false ) ;
2012-10-21 12:23:13 -07:00
2017-03-01 08:05:50 -08:00
fs : : create_directories ( GetDataDir ( ) / " blocks " ) ;
2012-12-12 13:11:52 -08:00
2012-11-04 08:11:48 -08:00
// cache size calculations
2015-05-03 16:56:42 -07:00
int64_t nTotalCache = ( GetArg ( " -dbcache " , nDefaultDbCache ) < < 20 ) ;
nTotalCache = std : : max ( nTotalCache , nMinDbCache < < 20 ) ; // total cache cannot be less than nMinDbCache
2021-11-12 02:02:19 -08:00
nTotalCache = std : : min ( nTotalCache , nMaxDbCache < < 20 ) ; // total cache cannot be greater than nMaxDbcache
2015-05-03 16:56:42 -07:00
int64_t nBlockTreeDBCache = nTotalCache / 8 ;
2015-06-27 12:21:41 -07:00
if ( nBlockTreeDBCache > ( 1 < < 21 ) & & ! GetBoolArg ( " -txindex " , DEFAULT_TXINDEX ) )
2012-11-04 08:11:48 -08:00
nBlockTreeDBCache = ( 1 < < 21 ) ; // block tree db cache shouldn't be larger than 2 MiB
2019-03-19 12:28:02 -07:00
// https://github.com/bitpay/bitcoin/commit/c91d78b578a8700a45be936cb5bb0931df8f4b87#diff-c865a8939105e6350a50af02766291b7R1233
if ( GetBoolArg ( " -insightexplorer " , false ) ) {
if ( ! GetBoolArg ( " -txindex " , false ) ) {
return InitError ( _ ( " -insightexplorer requires -txindex. " ) ) ;
}
// increase cache if additional indices are needed
nBlockTreeDBCache = nTotalCache * 3 / 4 ;
}
2012-11-04 08:11:48 -08:00
nTotalCache - = nBlockTreeDBCache ;
2015-05-03 16:56:42 -07:00
int64_t nCoinDBCache = std : : min ( nTotalCache / 2 , ( nTotalCache / 4 ) + ( 1 < < 23 ) ) ; // use 25%-50% of the remainder for disk cache
2012-11-04 08:11:48 -08:00
nTotalCache - = nCoinDBCache ;
2015-05-03 16:56:42 -07:00
nCoinCacheUsage = nTotalCache ; // the rest goes to in-memory cache
LogPrintf ( " Cache configuration: \n " ) ;
LogPrintf ( " * Using %.1fMiB for block index database \n " , nBlockTreeDBCache * ( 1.0 / 1024 / 1024 ) ) ;
LogPrintf ( " * Using %.1fMiB for chain state database \n " , nCoinDBCache * ( 1.0 / 1024 / 1024 ) ) ;
LogPrintf ( " * Using %.1fMiB for in-memory UTXO set \n " , nCoinCacheUsage * ( 1.0 / 1024 / 1024 ) ) ;
2012-11-04 08:11:48 -08:00
2018-07-31 14:29:14 -07:00
bool clearWitnessCaches = false ;
2013-02-16 08:58:45 -08:00
bool fLoaded = false ;
while ( ! fLoaded ) {
bool fReset = fReindex ;
std : : string strLoadError ;
2013-01-11 13:57:22 -08:00
2013-02-16 08:58:45 -08:00
uiInterface . InitMessage ( _ ( " Loading block index... " ) ) ;
2012-07-06 07:33:34 -07:00
2013-02-16 08:58:45 -08:00
nStart = GetTimeMillis ( ) ;
do {
try {
UnloadBlockIndex ( ) ;
delete pcoinsTip ;
delete pcoinsdbview ;
2015-01-08 05:38:06 -08:00
delete pcoinscatcher ;
2013-02-16 08:58:45 -08:00
delete pblocktree ;
pblocktree = new CBlockTreeDB ( nBlockTreeDBCache , false , fReindex ) ;
2016-04-21 05:14:37 -07:00
pcoinsdbview = new CCoinsViewDB ( nCoinDBCache , false , fReindex | | fReindexChainState ) ;
2015-01-08 05:38:06 -08:00
pcoinscatcher = new CCoinsViewErrorCatcher ( pcoinsdbview ) ;
pcoinsTip = new CCoinsViewCache ( pcoinscatcher ) ;
2013-02-16 08:58:45 -08:00
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
if ( fReindex ) {
2013-02-16 08:58:45 -08:00
pblocktree - > WriteReindexing ( true ) ;
2015-06-02 12:24:53 -07:00
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
if ( fPruneMode )
2015-06-02 12:24:53 -07:00
CleanupBlockRevFiles ( ) ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
}
2013-02-16 08:58:45 -08:00
if ( ! LoadBlockIndex ( ) ) {
strLoadError = _ ( " Error loading block database " ) ;
break ;
}
2013-05-12 03:03:32 -07:00
// If the loaded chain has a wrong genesis, bail out immediately
// (we're likely using a testnet datadir, or the other way around).
2015-04-09 06:58:34 -07:00
if ( ! mapBlockIndex . empty ( ) & & mapBlockIndex . count ( chainparams . GetConsensus ( ) . hashGenesisBlock ) = = 0 )
2013-05-12 03:03:32 -07:00
return InitError ( _ ( " Incorrect or no genesis block found. Wrong datadir for network? " ) ) ;
2013-02-16 08:58:45 -08:00
// Initialize the block index (no-op if non-empty database was already loaded)
2015-04-17 05:40:24 -07:00
if ( ! InitBlockIndex ( chainparams ) ) {
2013-02-16 08:58:45 -08:00
strLoadError = _ ( " Error initializing block database " ) ;
break ;
}
2013-06-22 07:03:11 -07:00
// Check for changed -txindex state
2015-06-27 12:21:41 -07:00
if ( fTxIndex ! = GetBoolArg ( " -txindex " , DEFAULT_TXINDEX ) ) {
2016-04-21 05:14:37 -07:00
strLoadError = _ ( " You need to rebuild the database using -reindex-chainstate to change -txindex " ) ;
2013-06-22 07:03:11 -07:00
break ;
}
2019-03-19 12:28:02 -07:00
// Check for changed -insightexplorer state
2020-01-27 06:59:24 -08:00
bool fInsightExplorerPreviouslySet = false ;
pblocktree - > ReadFlag ( " insightexplorer " , fInsightExplorerPreviouslySet ) ;
if ( fExperimentalInsightExplorer ! = fInsightExplorerPreviouslySet ) {
2019-03-19 12:28:02 -07:00
strLoadError = _ ( " You need to rebuild the database using -reindex to change -insightexplorer " ) ;
break ;
}
2020-03-13 04:13:33 -07:00
// Check for changed -lightwalletd state
bool fLightWalletdPreviouslySet = false ;
pblocktree - > ReadFlag ( " lightwalletd " , fLightWalletdPreviouslySet ) ;
if ( fExperimentalLightWalletd ! = fLightWalletdPreviouslySet ) {
strLoadError = _ ( " You need to rebuild the database using -reindex to change -lightwalletd " ) ;
break ;
}
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
// Check for changed -prune state. What we are concerned about is a user who has pruned blocks
// in the past, but is now trying to run unpruned.
if ( fHavePruned & & ! fPruneMode ) {
strLoadError = _ ( " You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain " ) ;
break ;
}
2016-03-18 09:20:12 -07:00
if ( ! fReindex ) {
2018-02-06 14:49:08 -08:00
uiInterface . InitMessage ( _ ( " Rewinding blocks if needed... " ) ) ;
2018-07-31 14:29:14 -07:00
if ( ! RewindBlockIndex ( chainparams , clearWitnessCaches ) ) {
2018-01-27 15:37:43 -08:00
strLoadError = _ ( " Unable to rewind the database to a pre-upgrade state. You will need to redownload the blockchain " ) ;
2016-03-18 09:20:12 -07:00
break ;
}
}
2013-02-23 14:48:02 -08:00
uiInterface . InitMessage ( _ ( " Verifying blocks... " ) ) ;
2015-06-27 12:08:36 -07:00
if ( fHavePruned & & GetArg ( " -checkblocks " , DEFAULT_CHECKBLOCKS ) > MIN_BLOCKS_TO_KEEP ) {
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
LogPrintf ( " Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail \n " ,
2015-06-27 12:08:36 -07:00
MIN_BLOCKS_TO_KEEP , GetArg ( " -checkblocks " , DEFAULT_CHECKBLOCKS ) ) ;
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
}
2015-07-28 14:42:03 -07:00
{
LOCK ( cs_main ) ;
CBlockIndex * tip = chainActive . Tip ( ) ;
2020-02-05 08:49:48 -08:00
if ( tip & & tip - > nTime > GetTime ( ) + 2 * 60 * 60 ) {
2015-07-28 14:42:03 -07:00
strLoadError = _ ( " The block database contains a block which appears to be from the future. "
" This may be due to your computer's date and time being set incorrectly. "
" Only rebuild the block database if you are sure that your computer's date and time are correct " ) ;
break ;
}
Add block pruning functionality
This adds a -prune=N option to bitcoind, which if set to N>0 will enable block
file pruning. When pruning is enabled, block and undo files will be deleted to
try to keep total space used by those files to below the prune target (N, in
MB) specified by the user, subject to some constraints:
- The last 288 blocks on the main chain are always kept (MIN_BLOCKS_TO_KEEP),
- N must be at least 550MB (chosen as a value for the target that could
reasonably be met, with some assumptions about block sizes, orphan rates,
etc; see comment in main.h),
- No blocks are pruned until chainActive is at least 100,000 blocks long (on
mainnet; defined separately for mainnet, testnet, and regtest in chainparams
as nPruneAfterHeight).
This unsets NODE_NETWORK if pruning is enabled.
Also included is an RPC test for pruning (pruning.py).
Thanks to @rdponticelli for earlier work on this feature; this is based in
part off that work.
2015-02-23 11:27:44 -08:00
}
2015-07-28 14:42:03 -07:00
2015-06-27 12:08:36 -07:00
if ( ! CVerifyDB ( ) . VerifyDB ( chainparams , pcoinsdbview , GetArg ( " -checklevel " , DEFAULT_CHECKLEVEL ) ,
GetArg ( " -checkblocks " , DEFAULT_CHECKBLOCKS ) ) ) {
2013-02-16 08:58:45 -08:00
strLoadError = _ ( " Corrupted block database detected " ) ;
break ;
}
2014-12-07 04:29:06 -08:00
} catch ( const std : : exception & e ) {
2013-09-18 03:38:08 -07:00
if ( fDebug ) LogPrintf ( " %s \n " , e . what ( ) ) ;
2013-02-16 08:58:45 -08:00
strLoadError = _ ( " Error opening block database " ) ;
break ;
}
2013-01-03 06:29:07 -08:00
2013-02-16 08:58:45 -08:00
fLoaded = true ;
} while ( false ) ;
if ( ! fLoaded ) {
// first suggest a reindex
if ( ! fReset ) {
2016-06-24 07:35:21 -07:00
bool fRet = uiInterface . ThreadSafeQuestion (
2013-05-12 23:26:29 -07:00
strLoadError + " . \n \n " + _ ( " Do you want to rebuild the block database now? " ) ,
2021-08-09 12:53:42 -07:00
strLoadError + " . \n Please restart with -reindex or -reindex-chainstate to recover. " ,
2013-02-16 08:58:45 -08:00
" " , CClientUIInterface : : MSG_ERROR | CClientUIInterface : : BTN_ABORT ) ;
if ( fRet ) {
fReindex = true ;
fRequestShutdown = false ;
} else {
2013-09-18 03:38:08 -07:00
LogPrintf ( " Aborted block database rebuild. Exiting. \n " ) ;
2013-02-16 08:58:45 -08:00
return false ;
}
} else {
return InitError ( strLoadError ) ;
}
}
}
2012-04-18 04:30:24 -07:00
2013-12-16 14:36:22 -08:00
// As LoadBlockIndex can take several minutes, it's possible the user
// requested to kill the GUI during the last operation. If so, exit.
2012-04-18 04:30:24 -07:00
// As the program has not fully started yet, Shutdown() is possibly overkill.
if ( fRequestShutdown )
{
2013-09-18 03:38:08 -07:00
LogPrintf ( " Shutdown requested. Exiting. \n " ) ;
2012-04-18 04:30:24 -07:00
return false ;
}
2014-02-24 00:08:56 -08:00
LogPrintf ( " block index %15dms \n " , GetTimeMillis ( ) - nStart ) ;
2011-05-14 11:10:21 -07:00
2017-03-01 08:05:50 -08:00
fs : : path est_path = GetDataDir ( ) / FEE_ESTIMATES_FILENAME ;
2017-03-01 08:28:39 -08:00
CAutoFile est_filein ( fsbridge : : fopen ( est_path , " rb " ) , SER_DISK , CLIENT_VERSION ) ;
2014-06-27 05:41:11 -07:00
// Allowed to fail as this file IS missing on first startup.
2014-10-20 03:45:50 -07:00
if ( ! est_filein . IsNull ( ) )
2014-03-17 05:19:54 -07:00
mempool . ReadFeeEstimates ( est_filein ) ;
2014-09-18 05:08:43 -07:00
fFeeEstimatesInitialized = true ;
2014-03-17 05:19:54 -07:00
2019-09-30 09:54:57 -07:00
2012-09-18 11:30:47 -07:00
// ********************************************************* Step 8: load wallet
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2013-10-02 08:19:10 -07:00
if ( fDisableWallet ) {
pwalletMain = NULL ;
LogPrintf ( " Wallet disabled! \n " ) ;
} else {
2021-09-21 12:23:47 -07:00
CWallet : : InitLoadWallet ( chainparams , clearWitnessCaches ) ;
2016-03-05 13:08:10 -08:00
if ( ! pwalletMain )
return false ;
2016-02-22 03:07:55 -08:00
}
2013-11-29 07:04:29 -08:00
# else // ENABLE_WALLET
2015-04-15 05:35:35 -07:00
LogPrintf ( " No wallet support compiled in! \n " ) ;
2013-11-29 07:04:29 -08:00
# endif // !ENABLE_WALLET
2015-06-30 10:22:48 -07:00
2017-01-30 08:24:07 -08:00
# ifdef ENABLE_MINING
2017-02-09 11:31:47 -08:00
# ifndef ENABLE_WALLET
2017-02-09 15:59:56 -08:00
if ( GetBoolArg ( " -minetolocalwallet " , false ) ) {
2017-02-09 11:31:47 -08:00
return InitError ( _ ( " Zcash was not built with wallet support. Set -minetolocalwallet=0 to use -mineraddress, or rebuild Zcash with wallet support. " ) ) ;
}
2017-02-09 15:59:56 -08:00
if ( GetArg ( " -mineraddress " , " " ) . empty ( ) & & GetBoolArg ( " -gen " , false ) ) {
2017-02-09 11:31:47 -08:00
return InitError ( _ ( " Zcash was not built with wallet support. Set -mineraddress, or rebuild Zcash with wallet support. " ) ) ;
}
# endif // !ENABLE_WALLET
2017-01-30 08:24:07 -08:00
if ( mapArgs . count ( " -mineraddress " ) ) {
2017-02-09 11:31:47 -08:00
# ifdef ENABLE_WALLET
2017-01-30 08:24:07 -08:00
bool minerAddressInLocalWallet = false ;
if ( pwalletMain ) {
2021-12-23 14:08:11 -08:00
auto zaddr = keyIO . DecodePaymentAddress ( mapArgs [ " -mineraddress " ] ) ;
if ( ! zaddr . has_value ( ) ) {
2022-01-10 18:41:26 -08:00
return InitError ( _ ( " -mineraddress is not a valid " PACKAGE_NAME " address. " ) ) ;
2019-05-17 15:36:32 -07:00
}
2022-02-09 12:49:36 -08:00
auto ztxoSelector = pwalletMain - > ZTXOSelectorForAddress ( zaddr . value ( ) , true ) ;
2022-01-25 06:39:22 -08:00
minerAddressInLocalWallet = ztxoSelector . has_value ( ) ;
2017-01-30 08:24:07 -08:00
}
2017-02-09 15:59:56 -08:00
if ( GetBoolArg ( " -minetolocalwallet " , true ) & & ! minerAddressInLocalWallet ) {
2017-01-30 08:24:07 -08:00
return InitError ( _ ( " -mineraddress is not in the local wallet. Either use a local address, or set -minetolocalwallet=0 " ) ) ;
}
2017-02-09 11:31:47 -08:00
# endif // ENABLE_WALLET
2015-04-10 03:49:01 -07:00
2019-01-28 10:46:08 -08:00
// This is leveraging the fact that boost::signals2 executes connected
// handlers in-order. Further up, the wallet is connected to this signal
2019-05-17 15:36:32 -07:00
// if the wallet is enabled. The wallet's AddressForMining handler does
// nothing if -mineraddress is set, and GetMinerAddress() does nothing
2020-03-05 14:47:45 -08:00
// if -mineraddress is not set (or set to an address that is not valid
// for mining).
2019-01-28 10:46:08 -08:00
//
2019-05-17 15:36:32 -07:00
// The upshot is that when AddressForMining(address) is called:
2019-01-28 10:46:08 -08:00
// - If -mineraddress is set (whether or not the wallet is enabled), the
2019-05-17 15:36:32 -07:00
// argument is set to -mineraddress.
// - If the wallet is enabled and -mineraddress is not set, the argument
// is set to a wallet address.
// - If the wallet is disabled and -mineraddress is not set, the
2019-01-28 10:46:08 -08:00
// argument is not modified; in practice this means it is empty, and
// GenerateBitcoins() returns an error.
2019-05-17 15:36:32 -07:00
GetMainSignals ( ) . AddressForMining . connect ( GetMinerAddress ) ;
2017-01-30 08:24:07 -08:00
}
# endif // ENABLE_MINING
2020-02-26 10:19:33 -08:00
// Start the thread that notifies listeners of transactions that have been
// recently added to the mempool, or have been added to or removed from the
2020-02-27 16:57:59 -08:00
// chain. We perform this before step 10 (import blocks) so that the
// original value of chainActive.Tip(), which corresponds with the wallet's
// view of the chaintip, is passed to ThreadNotifyWallets before the chain
// tip changes again.
2020-03-08 03:37:31 -07:00
{
CBlockIndex * pindexLastTip ;
{
LOCK ( cs_main ) ;
pindexLastTip = chainActive . Tip ( ) ;
}
boost : : function < void ( ) > threadnotifywallets = boost : : bind ( & ThreadNotifyWallets , pindexLastTip ) ;
threadGroup . create_thread (
boost : : bind ( & TraceThread < boost : : function < void ( ) > > , " txnotify " , threadnotifywallets )
) ;
}
2020-02-26 10:19:33 -08:00
2015-06-30 10:22:48 -07:00
// ********************************************************* Step 9: data directory maintenance
// if pruning, unset the service bit and perform the initial blockstore prune
// after any wallet rescanning has taken place.
if ( fPruneMode ) {
LogPrintf ( " Unsetting NODE_NETWORK on prune mode \n " ) ;
nLocalServices & = ~ NODE_NETWORK ;
if ( ! fReindex ) {
2015-10-19 11:43:04 -07:00
uiInterface . InitMessage ( _ ( " Pruning blockstore... " ) ) ;
2015-06-30 10:22:48 -07:00
PruneAndFlush ( ) ;
}
}
// ********************************************************* Step 10: import blocks
2012-01-03 07:14:22 -08:00
2014-08-14 09:32:34 -07:00
if ( mapArgs . count ( " -blocknotify " ) )
uiInterface . NotifyBlockTip . connect ( BlockNotifyCallback ) ;
2020-02-10 14:44:20 -08:00
if ( mapArgs . count ( " -txexpirynotify " ) )
uiInterface . NotifyTxExpiration . connect ( TxExpiryNotifyCallback ) ;
2017-03-01 08:05:50 -08:00
std : : vector < fs : : path > vImportFiles ;
2012-05-21 07:47:29 -07:00
if ( mapArgs . count ( " -loadblock " ) )
2011-05-14 11:10:21 -07:00
{
2017-06-01 18:18:57 -07:00
for ( const std : : string & strFile : mapMultiArgs [ " -loadblock " ] )
2013-03-06 19:31:26 -08:00
vImportFiles . push_back ( strFile ) ;
2012-09-24 10:37:03 -07:00
}
2020-07-10 10:34:53 -07:00
threadGroup . create_thread ( boost : : bind ( & ThreadImport , vImportFiles , chainparams ) ) ;
2016-05-16 20:33:32 -07:00
// Wait for genesis block to be processed
bool fHaveGenesis = false ;
while ( ! fHaveGenesis & & ! fRequestShutdown ) {
{
LOCK ( cs_main ) ;
fHaveGenesis = ( chainActive . Tip ( ) ! = NULL ) ;
}
if ( ! fHaveGenesis ) {
2014-11-07 23:18:21 -08:00
MilliSleep ( 10 ) ;
2016-05-16 20:33:32 -07:00
}
2014-11-07 23:18:21 -08:00
}
2020-03-08 04:06:29 -07:00
if ( ! fHaveGenesis ) {
return false ;
2014-11-07 23:18:21 -08:00
}
2012-09-24 10:37:03 -07:00
2015-06-30 10:22:48 -07:00
// ********************************************************* Step 11: start node
2011-05-14 11:10:21 -07:00
if ( ! CheckDiskSpace ( ) )
return false ;
2013-05-02 09:26:33 -07:00
if ( ! strErrors . str ( ) . empty ( ) )
return InitError ( strErrors . str ( ) ) ;
2012-05-21 07:47:29 -07:00
//// debug print
2017-08-22 02:02:25 -07:00
{
LOCK ( cs_main ) ;
LogPrintf ( " mapBlockIndex.size() = %u \n " , mapBlockIndex . size ( ) ) ;
LogPrintf ( " nBestHeight = %d \n " , chainActive . Height ( ) ) ;
}
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2017-08-22 02:02:25 -07:00
if ( pwalletMain )
{
LOCK ( pwalletMain - > cs_wallet ) ;
LogPrintf ( " setKeyPool.size() = %u \n " , pwalletMain - > setKeyPool . size ( ) ) ;
LogPrintf ( " mapWallet.size() = %u \n " , pwalletMain - > mapWallet . size ( ) ) ;
LogPrintf ( " mapAddressBook.size() = %u \n " , pwalletMain - > mapAddressBook . size ( ) ) ;
}
2013-11-29 07:04:29 -08:00
# endif
2012-05-21 07:47:29 -07:00
2015-08-25 11:12:08 -07:00
if ( GetBoolArg ( " -listenonion " , DEFAULT_LISTEN_ONION ) )
StartTorControl ( threadGroup , scheduler ) ;
2015-04-02 09:04:59 -07:00
StartNode ( threadGroup , scheduler ) ;
2015-06-21 08:49:50 -07:00
2016-12-22 20:30:27 -08:00
# ifdef ENABLE_MINING
2013-03-30 22:54:27 -07:00
// Generate coins in the background
2015-06-27 12:21:41 -07:00
GenerateBitcoins ( GetBoolArg ( " -gen " , DEFAULT_GENERATE ) , GetArg ( " -genproclimit " , DEFAULT_GENERATE_THREADS ) , chainparams ) ;
2013-11-29 07:04:29 -08:00
# endif
2013-03-30 22:54:27 -07:00
2015-09-11 14:31:30 -07:00
// ********************************************************* Step 12: finished
2012-05-21 07:47:29 -07:00
2014-10-29 10:08:31 -07:00
SetRPCWarmupFinished ( ) ;
2012-05-21 07:47:29 -07:00
uiInterface . InitMessage ( _ ( " Done loading " ) ) ;
2013-11-29 07:04:29 -08:00
# ifdef ENABLE_WALLET
2013-08-24 21:00:02 -07:00
if ( pwalletMain ) {
// Add wallet transactions that aren't already in a block to mapTransactions
pwalletMain - > ReacceptWalletTransactions ( ) ;
2012-05-21 07:47:29 -07:00
2013-08-24 21:00:02 -07:00
// Run a thread to flush wallet periodically
threadGroup . create_thread ( boost : : bind ( & ThreadFlushWalletDB , boost : : ref ( pwalletMain - > strWalletFile ) ) ) ;
}
2013-11-29 07:04:29 -08:00
# endif
2011-05-14 11:10:21 -07:00
2016-07-15 19:57:55 -07:00
// SENDALERT
threadGroup . create_thread ( boost : : bind ( ThreadSendAlert ) ) ;
2013-03-09 09:02:57 -08:00
return ! fRequestShutdown ;
2011-05-14 11:10:21 -07:00
}