aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.qt.include1
-rw-r--r--src/bitcoin-cli.cpp6
-rw-r--r--src/chain.cpp5
-rw-r--r--src/chain.h36
-rw-r--r--src/chainparams.cpp9
-rw-r--r--src/chainparamsbase.cpp25
-rw-r--r--src/chainparamsbase.h9
-rw-r--r--src/core.h13
-rw-r--r--src/init.cpp98
-rw-r--r--src/main.cpp871
-rw-r--r--src/main.h54
-rw-r--r--src/miner.cpp1
-rw-r--r--src/net.cpp56
-rw-r--r--src/net.h4
-rw-r--r--src/noui.cpp6
-rw-r--r--src/pow.cpp33
-rw-r--r--src/pow.h2
-rw-r--r--src/qt/bitcoingui.cpp5
-rw-r--r--src/qt/bitcoinstrings.cpp104
-rw-r--r--src/qt/forms/rpcconsole.ui23
-rw-r--r--src/qt/intro.cpp4
-rw-r--r--src/qt/locale/bitcoin_en.ts673
-rw-r--r--src/qt/rpcconsole.cpp1
-rw-r--r--src/rpcblockchain.cpp2
-rw-r--r--src/rpcnet.cpp16
-rw-r--r--src/rpcserver.cpp2
-rw-r--r--src/serialize.h19
-rw-r--r--src/test/DoS_tests.cpp45
-rw-r--r--src/test/bloom_tests.cpp1
-rw-r--r--src/test/checkblock_tests.cpp2
-rw-r--r--src/test/test_bitcoin.cpp2
-rw-r--r--src/txmempool.h13
-rw-r--r--src/ui_interface.h3
-rw-r--r--src/util.cpp12
-rw-r--r--src/version.h5
-rw-r--r--src/wallet.h2
36 files changed, 1074 insertions, 1089 deletions
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 872a0cf1c5..f8f4439159 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -368,6 +368,7 @@ if USE_LIBSECP256K1
qt_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la
endif
qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS)
+qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX
#locale/foo.ts -> locale/foo.qm
QT_QM=$(QT_TS:.ts=.qm)
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index badb376cb3..aa5e285b10 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -25,13 +25,13 @@ std::string HelpMessageCli()
string strUsage;
strUsage += _("Options:") + "\n";
strUsage += " -? " + _("This help message") + "\n";
- strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n";
+ strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
strUsage += " -testnet " + _("Use the test network") + "\n";
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be "
"solved instantly. This is intended for regression testing tools and app development.") + "\n";
- strUsage += " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n";
- strUsage += " -rpcport=<port> " + _("Connect to JSON-RPC on <port> (default: 8332 or testnet: 18332)") + "\n";
+ strUsage += " -rpcconnect=<ip> " + strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1") + "\n";
+ strUsage += " -rpcport=<port> " + strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n";
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
diff --git a/src/chain.cpp b/src/chain.cpp
index 05427a4569..56ed22ce71 100644
--- a/src/chain.cpp
+++ b/src/chain.cpp
@@ -9,17 +9,16 @@ using namespace std;
// CChain implementation
-CBlockIndex *CChain::SetTip(CBlockIndex *pindex) {
+void CChain::SetTip(CBlockIndex *pindex) {
if (pindex == NULL) {
vChain.clear();
- return NULL;
+ return;
}
vChain.resize(pindex->nHeight + 1);
while (pindex && vChain[pindex->nHeight] != pindex) {
vChain[pindex->nHeight] = pindex;
pindex = pindex->pprev;
}
- return pindex;
}
CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
diff --git a/src/chain.h b/src/chain.h
index 961919d97e..290150476e 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -50,12 +50,29 @@ struct CDiskBlockPos
};
enum BlockStatus {
+ // Unused.
BLOCK_VALID_UNKNOWN = 0,
- BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
- BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint
- BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root
- BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30
- BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok
+
+ // Parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
+ BLOCK_VALID_HEADER = 1,
+
+ // All parent headers found, difficulty matches, timestamp >= median previous, checkpoint. Implies all parents
+ // are also at least TREE.
+ BLOCK_VALID_TREE = 2,
+
+ // Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids,
+ // sigops, size, merkle root. Implies all parents are at least TREE but not necessarily TRANSACTIONS. When all
+ // parent blocks also have TRANSACTIONS, CBlockIndex::nChainTx will be set.
+ BLOCK_VALID_TRANSACTIONS = 3,
+
+ // Outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30.
+ // Implies all parents are also at least CHAIN.
+ BLOCK_VALID_CHAIN = 4,
+
+ // Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
+ BLOCK_VALID_SCRIPTS = 5,
+
+ // All validity bits.
BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS,
@@ -104,7 +121,8 @@ public:
// Note: in a potential headers-first mode, this number cannot be relied upon
unsigned int nTx;
- // (memory only) Number of transactions in the chain up to and including this block
+ // (memory only) Number of transactions in the chain up to and including this block.
+ // This value will be non-zero only if and only if transactions for this block and all its parents are available.
unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030
// Verification status of this block. See enum BlockStatus
@@ -147,7 +165,7 @@ public:
SetNull();
}
- CBlockIndex(CBlockHeader& block)
+ CBlockIndex(const CBlockHeader& block)
{
SetNull();
@@ -378,8 +396,8 @@ public:
return vChain.size() - 1;
}
- /** Set/initialize a chain with a given tip. Returns the forking point. */
- CBlockIndex *SetTip(CBlockIndex *pindex);
+ /** Set/initialize a chain with a given tip. */
+ void SetTip(CBlockIndex *pindex);
/** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const;
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 6896076245..dd76ca6c26 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -355,10 +355,13 @@ void SelectParams(CBaseChainParams::Network network) {
pCurrentParams = &Params(network);
}
-bool SelectParamsFromCommandLine() {
- if (!SelectBaseParamsFromCommandLine())
+bool SelectParamsFromCommandLine()
+{
+ CBaseChainParams::Network network = NetworkIdFromCommandLine();
+ if (network == CBaseChainParams::MAX_NETWORK_TYPES)
return false;
- SelectParams(BaseParams().NetworkID());
+ SelectBaseParams(network);
+ SelectParams(network);
return true;
}
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index e9d63197bd..5d9ec7927b 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -100,22 +100,27 @@ void SelectBaseParams(CBaseChainParams::Network network)
}
}
-bool SelectBaseParamsFromCommandLine()
+CBaseChainParams::Network NetworkIdFromCommandLine()
{
bool fRegTest = GetBoolArg("-regtest", false);
bool fTestNet = GetBoolArg("-testnet", false);
- if (fTestNet && fRegTest) {
+ if (fTestNet && fRegTest)
+ return CBaseChainParams::MAX_NETWORK_TYPES;
+ if (fRegTest)
+ return CBaseChainParams::REGTEST;
+ if (fTestNet)
+ return CBaseChainParams::TESTNET;
+ return CBaseChainParams::MAIN;
+}
+
+bool SelectBaseParamsFromCommandLine()
+{
+ CBaseChainParams::Network network = NetworkIdFromCommandLine();
+ if (network == CBaseChainParams::MAX_NETWORK_TYPES)
return false;
- }
- if (fRegTest) {
- SelectBaseParams(CBaseChainParams::REGTEST);
- } else if (fTestNet) {
- SelectBaseParams(CBaseChainParams::TESTNET);
- } else {
- SelectBaseParams(CBaseChainParams::MAIN);
- }
+ SelectBaseParams(network);
return true;
}
diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h
index cc154cf501..911d1181ac 100644
--- a/src/chainparamsbase.h
+++ b/src/chainparamsbase.h
@@ -26,7 +26,6 @@ public:
const std::string& DataDir() const { return strDataDir; }
int RPCPort() const { return nRPCPort; }
- Network NetworkID() const { return networkID; }
protected:
CBaseChainParams() {}
@@ -46,7 +45,13 @@ const CBaseChainParams& BaseParams();
void SelectBaseParams(CBaseChainParams::Network network);
/**
- * Looks for -regtest or -testnet and then calls SelectParams as appropriate.
+ * Looks for -regtest or -testnet and returns the appropriate Network ID.
+ * Returns MAX_NETWORK_TYPES if an invalid combination is given.
+ */
+CBaseChainParams::Network NetworkIdFromCommandLine();
+
+/**
+ * Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate.
* Returns false if an invalid combination is given.
*/
bool SelectBaseParamsFromCommandLine();
diff --git a/src/core.h b/src/core.h
index a348293578..a024dad740 100644
--- a/src/core.h
+++ b/src/core.h
@@ -61,19 +61,6 @@ public:
std::string ToString() const;
};
-/** An inpoint - a combination of a transaction and an index n into its vin */
-class CInPoint
-{
-public:
- const CTransaction* ptx;
- uint32_t n;
-
- CInPoint() { SetNull(); }
- CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; }
- void SetNull() { ptx = NULL; n = (uint32_t) -1; }
- bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); }
-};
-
/** An input of a transaction. It contains the location of the previous
* transaction's output that it claims and a signature that matches the
* output's public key.
diff --git a/src/init.cpp b/src/init.cpp
index 8772be5539..70ac5190d3 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -139,7 +139,7 @@ void Shutdown()
{
boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
CAutoFile est_fileout(fopen(est_path.string().c_str(), "wb"), SER_DISK, CLIENT_VERSION);
- if (est_fileout)
+ if (!est_fileout.IsNull())
mempool.WriteFeeEstimates(est_fileout);
else
LogPrintf("%s: Failed to write fee estimates to %s\n", __func__, est_path.string());
@@ -170,7 +170,7 @@ void Shutdown()
#ifndef WIN32
boost::filesystem::remove(GetPidFile());
#endif
- UnregisterAllWallets();
+ UnregisterAllValidationInterfaces();
#ifdef ENABLE_WALLET
delete pwalletMain;
pwalletMain = NULL;
@@ -222,9 +222,9 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -? " + _("This help message") + "\n";
strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n";
strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
- strUsage += " -checkblocks=<n> " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n";
- strUsage += " -checklevel=<n> " + _("How thorough the block verification of -checkblocks is (0-4, default: 3)") + "\n";
- strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n";
+ strUsage += " -checkblocks=<n> " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n";
+ strUsage += " -checklevel=<n> " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n";
+ strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
if (mode == HMM_BITCOIND)
{
#if !defined(WIN32)
@@ -238,33 +238,33 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
#ifndef WIN32
- strUsage += " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n";
+ strUsage += " -pid=<file> " + strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid") + "\n";
#endif
strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n";
#if !defined(WIN32)
strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n";
#endif
- strUsage += " -txindex " + _("Maintain a full transaction index, used by the getrawtransaction rpc call (default: 0)") + "\n";
+ strUsage += " -txindex " + strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0) + "\n";
strUsage += "\n" + _("Connection options:") + "\n";
strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
- strUsage += " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n";
- strUsage += " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n";
+ strUsage += " -banscore=<n> " + strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100) + "\n";
+ strUsage += " -bantime=<n> " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n";
strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n";
strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n";
strUsage += " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n";
strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n";
strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n";
strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n";
- strUsage += " -forcednsseed " + _("Always query for peer addresses via DNS lookup (default: 0)") + "\n";
+ strUsage += " -forcednsseed " + strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0) + "\n";
strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n";
- strUsage += " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n";
- strUsage += " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)") + "\n";
- strUsage += " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)") + "\n";
- strUsage += " -onion=<ip:port> " + _("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)") + "\n";
+ strUsage += " -maxconnections=<n> " + strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125) + "\n";
+ strUsage += " -maxreceivebuffer=<n> " + strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000) + "\n";
+ strUsage += " -maxsendbuffer=<n> " + strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000) + "\n";
+ strUsage += " -onion=<ip:port> " + strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy") + "\n";
strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)") + "\n";
- strUsage += " -permitbaremultisig " + _("Relay non-P2SH multisig (default: 1)") + "\n";
- strUsage += " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n";
+ strUsage += " -permitbaremultisig " + strprintf(_("Relay non-P2SH multisig (default: %u)"), 1) + "\n";
+ strUsage += " -port=<port> " + strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333) + "\n";
strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
strUsage += " -timeout=<n> " + strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT) + "\n";
@@ -272,44 +272,44 @@ std::string HelpMessage(HelpMessageMode mode)
#if USE_UPNP
strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n";
#else
- strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n";
+ strUsage += " -upnp " + strprintf(_("Use UPnP to map the listening port (default: %u)"), 0) + "\n";
#endif
#endif
strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n";
- strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.") + "\n";
+ strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + "\n";
strUsage += " " + _("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") + "\n";
#ifdef ENABLE_WALLET
strUsage += "\n" + _("Wallet options:") + "\n";
strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n";
- strUsage += " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n";
+ strUsage += " -keypool=<n> " + strprintf(_("Set key pool size to <n> (default: %u)"), 100) + "\n";
if (GetBoolArg("-help-debug", false))
strUsage += " -mintxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n";
strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
- strUsage += " -spendzeroconfchange " + _("Spend unconfirmed change when sending transactions (default: 1)") + "\n";
- strUsage += " -txconfirmtarget=<n> " + _("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)") + "\n";
+ strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n";
+ strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)"), 1) + "\n";
strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
- strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + _("(default: wallet.dat)") + "\n";
+ strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n";
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + "\n";
- strUsage += " " + _("(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
+ strUsage += " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
#endif
strUsage += "\n" + _("Debugging/Testing options:") + "\n";
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -checkpoints " + _("Only accept block chain matching built-in checkpoints (default: 1)") + "\n";
- strUsage += " -dblogsize=<n> " + _("Flush database activity from memory pool to disk log every <n> megabytes (default: 100)") + "\n";
- strUsage += " -disablesafemode " + _("Disable safemode, override a real safe mode event (default: 0)") + "\n";
- strUsage += " -testsafemode " + _("Force safe mode (default: 0)") + "\n";
+ strUsage += " -checkpoints " + strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1) + "\n";
+ strUsage += " -dblogsize=<n> " + strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100) + "\n";
+ strUsage += " -disablesafemode " + strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0) + "\n";
+ strUsage += " -testsafemode " + strprintf(_("Force safe mode (default: %u)"), 0) + "\n";
strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n";
strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n";
- strUsage += " -flushwallet " + _("Run a thread to flush wallet periodically (default: 1)") + "\n";
- strUsage += " -stopafterblockimport " + _("Stop running after importing blocks from disk (default: 0)") + "\n";
+ strUsage += " -flushwallet " + strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1) + "\n";
+ strUsage += " -stopafterblockimport " + strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0) + "\n";
}
- strUsage += " -debug=<category> " + _("Output debugging information (default: 0, supplying <category> is optional)") + "\n";
+ strUsage += " -debug=<category> " + strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + "\n";
strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n";
strUsage += " " + _("<category> can be:");
strUsage += " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
@@ -317,25 +317,25 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += ", qt";
strUsage += ".\n";
#ifdef ENABLE_WALLET
- strUsage += " -gen " + _("Generate coins (default: 0)") + "\n";
- strUsage += " -genproclimit=<n> " + _("Set the processor limit for when generation is on (-1 = unlimited, default: -1)") + "\n";
+ strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n";
+ strUsage += " -genproclimit=<n> " + strprintf(_("Set the processor limit for when generation is on (-1 = unlimited, default: %d)"), -1) + "\n";
#endif
strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
- strUsage += " -logips " + _("Include IP addresses in debug output (default: 0)") + "\n";
- strUsage += " -logtimestamps " + _("Prepend debug output with timestamp (default: 1)") + "\n";
+ strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n";
+ strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n";
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -limitfreerelay=<n> " + _("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)") + "\n";
- strUsage += " -maxsigcachesize=<n> " + _("Limit size of signature cache to <n> entries (default: 50000)") + "\n";
+ strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
+ strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
}
strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n";
if (GetBoolArg("-help-debug", false))
{
strUsage += " -printblock=<hash> " + _("Print block on startup, if found in block index") + "\n";
- strUsage += " -printblocktree " + _("Print block tree on startup (default: 0)") + "\n";
- strUsage += " -printpriority " + _("Log transaction priority and fee per kB when mining blocks (default: 0)") + "\n";
- strUsage += " -privdb " + _("Sets the DB_PRIVATE flag in the wallet db environment (default: 1)") + "\n";
+ strUsage += " -printblocktree " + strprintf(_("Print block tree on startup (default: %u)"), 0) + "\n";
+ strUsage += " -printpriority " + strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0) + "\n";
+ strUsage += " -privdb " + strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1) + "\n";
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n";
strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n";
@@ -344,10 +344,10 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -testnet " + _("Use the test network") + "\n";
strUsage += "\n" + _("Node relay options:") + "\n";
- strUsage += " -datacarrier " + _("Relay and mine data carrier transactions (default: 1)") + "\n";
+ strUsage += " -datacarrier " + strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1) + "\n";
strUsage += "\n" + _("Block creation options:") + "\n";
- strUsage += " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n";
+ strUsage += " -blockminsize=<n> " + strprintf(_("Set minimum block size in bytes (default: %u)"), 0) + "\n";
strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
strUsage += " -blockprioritysize=<n> " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n";
@@ -356,15 +356,15 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -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)") + "\n";
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
- strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)") + "\n";
+ strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
strUsage += " -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") + "\n";
- strUsage += " -rpcthreads=<n> " + _("Set the number of threads to service RPC calls (default: 4)") + "\n";
+ strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
- strUsage += " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n";
- strUsage += " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n";
- strUsage += " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)") + "\n";
+ strUsage += " -rpcsslcertificatechainfile=<file.cert> " + strprintf(_("Server certificate file (default: %s)"), "server.cert") + "\n";
+ strUsage += " -rpcsslprivatekeyfile=<file.pem> " + strprintf(_("Server private key (default: %s)"), "server.pem") + "\n";
+ strUsage += " -rpcsslciphers=<ciphers> " + strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH") + "\n";
return strUsage;
}
@@ -974,7 +974,7 @@ bool AppInit2(boost::thread_group& threadGroup)
// If the loaded chain has a wrong genesis, bail out immediately
// (we're likely using a testnet datadir, or the other way around).
- if (!mapBlockIndex.empty() && chainActive.Genesis() == NULL)
+ if (!mapBlockIndex.empty() && mapBlockIndex.count(Params().HashGenesisBlock()) == 0)
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
// Initialize the block index (no-op if non-empty database was already loaded)
@@ -1064,7 +1064,7 @@ bool AppInit2(boost::thread_group& threadGroup)
boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
CAutoFile est_filein(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION);
// Allowed to fail as this file IS missing on first startup.
- if (est_filein)
+ if (!est_filein.IsNull())
mempool.ReadFeeEstimates(est_filein);
fFeeEstimatesInitialized = true;
@@ -1154,7 +1154,7 @@ bool AppInit2(boost::thread_group& threadGroup)
LogPrintf("%s", strErrors.str());
LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
- RegisterWallet(pwalletMain);
+ RegisterValidationInterface(pwalletMain);
CBlockIndex *pindexRescan = chainActive.Tip();
if (GetBoolArg("-rescan", false))
diff --git a/src/main.cpp b/src/main.cpp
index fc8167e40e..0cfe90beda 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -41,6 +41,7 @@ CCriticalSection cs_main;
BlockMap mapBlockIndex;
CChain chainActive;
+CBlockIndex *pindexBestHeader = NULL;
int64_t nTimeBestReceived = 0;
CWaitableCriticalSection csBestBlock;
CConditionVariable cvBlockChange;
@@ -51,19 +52,12 @@ bool fTxIndex = false;
bool fIsBareMultisigStd = true;
unsigned int nCoinCacheSize = 5000;
+
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
CFeeRate minRelayTxFee = CFeeRate(1000);
CTxMemPool mempool(::minRelayTxFee);
-struct COrphanBlock {
- uint256 hashBlock;
- uint256 hashPrev;
- vector<unsigned char> vchBlock;
-};
-map<uint256, COrphanBlock*> mapOrphanBlocks;
-multimap<uint256, COrphanBlock*> mapOrphanBlocksByPrev;
-
struct COrphanTx {
CTransaction tx;
NodeId fromPeer;
@@ -105,10 +99,14 @@ namespace {
// The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least
// as good as our current tip. Entries may be failed, though.
- set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid;
+ set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
+ // Number of nodes with fSyncStarted.
+ int nSyncStarted = 0;
+ // All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
+ multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
CCriticalSection cs_LastBlockFile;
- CBlockFileInfo infoLastBlockFile;
+ std::vector<CBlockFileInfo> vinfoBlockFile;
int nLastBlockFile = 0;
// Every received block is assigned a unique and increasing identifier, so we
@@ -125,11 +123,10 @@ namespace {
// Protected by cs_main.
struct QueuedBlock {
uint256 hash;
+ CBlockIndex *pindex; // Optional.
int64_t nTime; // Time of "getdata" request in microseconds.
- int nQueuedBefore; // Number of blocks in flight at the time of request.
};
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
- map<uint256, pair<NodeId, list<uint256>::iterator> > mapBlocksToDownload;
} // anon namespace
@@ -159,25 +156,25 @@ struct CMainSignals {
} // anon namespace
-void RegisterWallet(CWalletInterface* pwalletIn) {
- g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2));
- g_signals.EraseTransaction.connect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
- g_signals.UpdatedTransaction.connect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
- g_signals.SetBestChain.connect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
- g_signals.Inventory.connect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1));
- g_signals.Broadcast.connect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn));
+void RegisterValidationInterface(CValidationInterface* pwalletIn) {
+ g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
+ g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
+ g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
+ g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
+ g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
+ g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
}
-void UnregisterWallet(CWalletInterface* pwalletIn) {
- g_signals.Broadcast.disconnect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn));
- g_signals.Inventory.disconnect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1));
- g_signals.SetBestChain.disconnect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
- g_signals.UpdatedTransaction.disconnect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
- g_signals.EraseTransaction.disconnect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
- g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2));
+void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
+ g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
+ g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
+ g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
+ g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
+ g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
+ g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
}
-void UnregisterAllWallets() {
+void UnregisterAllValidationInterfaces() {
g_signals.Broadcast.disconnect_all_slots();
g_signals.Inventory.disconnect_all_slots();
g_signals.SetBestChain.disconnect_all_slots();
@@ -220,22 +217,24 @@ struct CNodeState {
CBlockIndex *pindexBestKnownBlock;
// The hash of the last unknown block this peer has announced.
uint256 hashLastUnknownBlock;
+ // The last full block we both have.
+ CBlockIndex *pindexLastCommonBlock;
+ // Whether we've started headers synchronization with this peer.
+ bool fSyncStarted;
+ // Since when we're stalling block download progress (in microseconds), or 0.
+ int64_t nStallingSince;
list<QueuedBlock> vBlocksInFlight;
int nBlocksInFlight;
- list<uint256> vBlocksToDownload;
- int nBlocksToDownload;
- int64_t nLastBlockReceive;
- int64_t nLastBlockProcess;
CNodeState() {
nMisbehavior = 0;
fShouldBan = false;
pindexBestKnownBlock = NULL;
hashLastUnknownBlock = uint256(0);
- nBlocksToDownload = 0;
+ pindexLastCommonBlock = NULL;
+ fSyncStarted = false;
+ nStallingSince = 0;
nBlocksInFlight = 0;
- nLastBlockReceive = 0;
- nLastBlockProcess = 0;
}
};
@@ -266,64 +265,37 @@ void FinalizeNode(NodeId nodeid) {
LOCK(cs_main);
CNodeState *state = State(nodeid);
+ if (state->fSyncStarted)
+ nSyncStarted--;
+
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
mapBlocksInFlight.erase(entry.hash);
- BOOST_FOREACH(const uint256& hash, state->vBlocksToDownload)
- mapBlocksToDownload.erase(hash);
EraseOrphansFor(nodeid);
mapNodeState.erase(nodeid);
}
// Requires cs_main.
-void MarkBlockAsReceived(const uint256 &hash, NodeId nodeFrom = -1) {
- map<uint256, pair<NodeId, list<uint256>::iterator> >::iterator itToDownload = mapBlocksToDownload.find(hash);
- if (itToDownload != mapBlocksToDownload.end()) {
- CNodeState *state = State(itToDownload->second.first);
- state->vBlocksToDownload.erase(itToDownload->second.second);
- state->nBlocksToDownload--;
- mapBlocksToDownload.erase(itToDownload);
- }
-
+void MarkBlockAsReceived(const uint256& hash) {
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
if (itInFlight != mapBlocksInFlight.end()) {
CNodeState *state = State(itInFlight->second.first);
state->vBlocksInFlight.erase(itInFlight->second.second);
state->nBlocksInFlight--;
- if (itInFlight->second.first == nodeFrom)
- state->nLastBlockReceive = GetTimeMicros();
+ state->nStallingSince = 0;
mapBlocksInFlight.erase(itInFlight);
}
}
// Requires cs_main.
-bool AddBlockToQueue(NodeId nodeid, const uint256 &hash) {
- if (mapBlocksToDownload.count(hash) || mapBlocksInFlight.count(hash))
- return false;
-
- CNodeState *state = State(nodeid);
- if (state == NULL)
- return false;
-
- list<uint256>::iterator it = state->vBlocksToDownload.insert(state->vBlocksToDownload.end(), hash);
- state->nBlocksToDownload++;
- if (state->nBlocksToDownload > 5000)
- Misbehaving(nodeid, 10);
- mapBlocksToDownload[hash] = std::make_pair(nodeid, it);
- return true;
-}
-
-// Requires cs_main.
-void MarkBlockAsInFlight(NodeId nodeid, const uint256 &hash) {
+void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex = NULL) {
CNodeState *state = State(nodeid);
assert(state != NULL);
// Make sure it's not listed somewhere already.
MarkBlockAsReceived(hash);
- QueuedBlock newentry = {hash, GetTimeMicros(), state->nBlocksInFlight};
- if (state->nBlocksInFlight == 0)
- state->nLastBlockReceive = newentry.nTime; // Reset when a first request is sent.
+ QueuedBlock newentry = {hash, pindex, GetTimeMicros()};
list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
state->nBlocksInFlight++;
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
@@ -362,6 +334,104 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
}
}
+/** Find the last common ancestor two blocks have.
+ * Both pa and pb must be non-NULL. */
+CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
+ if (pa->nHeight > pb->nHeight) {
+ pa = pa->GetAncestor(pb->nHeight);
+ } else if (pb->nHeight > pa->nHeight) {
+ pb = pb->GetAncestor(pa->nHeight);
+ }
+
+ while (pa != pb && pa && pb) {
+ pa = pa->pprev;
+ pb = pb->pprev;
+ }
+
+ // Eventually all chain branches meet at the genesis block.
+ assert(pa == pb);
+ return pa;
+}
+
+/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
+ * at most count entries. */
+void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
+ if (count == 0)
+ return;
+
+ vBlocks.reserve(vBlocks.size() + count);
+ CNodeState *state = State(nodeid);
+ assert(state != NULL);
+
+ // Make sure pindexBestKnownBlock is up to date, we'll need it.
+ ProcessBlockAvailability(nodeid);
+
+ if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
+ // This peer has nothing interesting.
+ return;
+ }
+
+ if (state->pindexLastCommonBlock == NULL) {
+ // Bootstrap quickly by guessing a parent of our best tip is the forking point.
+ // Guessing wrong in either direction is not a problem.
+ state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
+ }
+
+ // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
+ // of their current tip anymore. Go back enough to fix that.
+ state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
+ if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
+ return;
+
+ std::vector<CBlockIndex*> vToFetch;
+ CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
+ // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
+ // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
+ // download that next block if the window were 1 larger.
+ int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
+ int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
+ NodeId waitingfor = -1;
+ while (pindexWalk->nHeight < nMaxHeight) {
+ // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
+ // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
+ // as iterating over ~100 CBlockIndex* entries anyway.
+ int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
+ vToFetch.resize(nToFetch);
+ pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
+ vToFetch[nToFetch - 1] = pindexWalk;
+ for (unsigned int i = nToFetch - 1; i > 0; i--) {
+ vToFetch[i - 1] = vToFetch[i]->pprev;
+ }
+
+ // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
+ // are not yet downloaded and not in flight to vBlocks. In the mean time, update
+ // pindexLastCommonBlock as long as all ancestors are already downloaded.
+ BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
+ if (pindex->nStatus & BLOCK_HAVE_DATA) {
+ if (pindex->nChainTx)
+ state->pindexLastCommonBlock = pindex;
+ } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
+ // The block is not already downloaded, and not yet in flight.
+ if (pindex->nHeight > nWindowEnd) {
+ // We reached the end of the window.
+ if (vBlocks.size() == 0 && waitingfor != nodeid) {
+ // We aren't able to fetch anything, but we would be if the download window was one larger.
+ nodeStaller = waitingfor;
+ }
+ return;
+ }
+ vBlocks.push_back(pindex);
+ if (vBlocks.size() == count) {
+ return;
+ }
+ } else if (waitingfor == -1) {
+ // This is the first already-in-flight block.
+ waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
+ }
+ }
+ }
+}
+
} // anon namespace
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
@@ -371,6 +441,11 @@ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
return false;
stats.nMisbehavior = state->nMisbehavior;
stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
+ stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
+ BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
+ if (queue.pindex)
+ stats.vHeightInFlight.push_back(queue.pindex->nHeight);
+ }
return true;
}
@@ -976,7 +1051,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
CBlockHeader header;
try {
file >> header;
- fseek(file, postx.nTxOffset, SEEK_CUR);
+ fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
file >> txOut;
} catch (std::exception &e) {
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
@@ -1031,7 +1106,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
{
// Open history file to append
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
- if (!fileout)
+ if (fileout.IsNull())
return error("WriteBlockToDisk : OpenBlockFile failed");
// Write index header
@@ -1039,16 +1114,16 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
fileout << FLATDATA(Params().MessageStart()) << nSize;
// Write block
- long fileOutPos = ftell(fileout);
+ long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
return error("WriteBlockToDisk : ftell failed");
pos.nPos = (unsigned int)fileOutPos;
fileout << block;
// Flush stdio buffers and commit to disk before returning
- fflush(fileout);
+ fflush(fileout.Get());
if (!IsInitialBlockDownload())
- FileCommit(fileout);
+ FileCommit(fileout.Get());
return true;
}
@@ -1059,7 +1134,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
// Open history file to read
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (!filein)
+ if (filein.IsNull())
return error("ReadBlockFromDisk : OpenBlockFile failed");
// Read block
@@ -1086,46 +1161,6 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
return true;
}
-uint256 static GetOrphanRoot(const uint256& hash)
-{
- map<uint256, COrphanBlock*>::iterator it = mapOrphanBlocks.find(hash);
- if (it == mapOrphanBlocks.end())
- return hash;
-
- // Work back to the first block in the orphan chain
- do {
- map<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocks.find(it->second->hashPrev);
- if (it2 == mapOrphanBlocks.end())
- return it->first;
- it = it2;
- } while(true);
-}
-
-// Remove a random orphan block (which does not have any dependent orphans).
-void static PruneOrphanBlocks()
-{
- if (mapOrphanBlocksByPrev.size() <= (size_t)std::max((int64_t)0, GetArg("-maxorphanblocks", DEFAULT_MAX_ORPHAN_BLOCKS)))
- return;
-
- // Pick a random orphan block.
- int pos = insecure_rand() % mapOrphanBlocksByPrev.size();
- std::multimap<uint256, COrphanBlock*>::iterator it = mapOrphanBlocksByPrev.begin();
- while (pos--) it++;
-
- // As long as this block has other orphans depending on it, move to one of those successors.
- do {
- std::multimap<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocksByPrev.find(it->second->hashBlock);
- if (it2 == mapOrphanBlocksByPrev.end())
- break;
- it = it2;
- } while(1);
-
- uint256 hash = it->second->hashBlock;
- delete it->second;
- mapOrphanBlocksByPrev.erase(it);
- mapOrphanBlocks.erase(hash);
-}
-
CAmount GetBlockValue(int nHeight, const CAmount& nFees)
{
int64_t nSubsidy = 50 * COIN;
@@ -1284,7 +1319,7 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state
if (!state.CorruptionPossible()) {
pindex->nStatus |= BLOCK_FAILED_VALID;
pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex));
- setBlockIndexValid.erase(pindex);
+ setBlockIndexCandidates.erase(pindex);
InvalidChainFound(pindex);
}
}
@@ -1512,7 +1547,7 @@ void static FlushBlockFile(bool fFinalize = false)
FILE *fileOld = OpenBlockFile(posOld);
if (fileOld) {
if (fFinalize)
- TruncateFile(fileOld, infoLastBlockFile.nSize);
+ TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
FileCommit(fileOld);
fclose(fileOld);
}
@@ -1520,7 +1555,7 @@ void static FlushBlockFile(bool fFinalize = false)
fileOld = OpenUndoFile(posOld);
if (fileOld) {
if (fFinalize)
- TruncateFile(fileOld, infoLastBlockFile.nUndoSize);
+ TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
FileCommit(fileOld);
fclose(fileOld);
}
@@ -1664,11 +1699,6 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
if (fJustCheck)
return true;
- // Correct transaction counts.
- pindex->nTx = block.vtx.size();
- if (pindex->pprev)
- pindex->nChainTx = pindex->pprev->nChainTx + block.vtx.size();
-
// Write undo information to disk
if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
{
@@ -1889,8 +1919,8 @@ static CBlockIndex* FindMostWorkChain() {
// Find the best candidate header.
{
- std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexValid.rbegin();
- if (it == setBlockIndexValid.rend())
+ std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
+ if (it == setBlockIndexCandidates.rend())
return NULL;
pindexNew = *it;
}
@@ -1900,6 +1930,8 @@ static CBlockIndex* FindMostWorkChain() {
CBlockIndex *pindexTest = pindexNew;
bool fInvalidAncestor = false;
while (pindexTest && !chainActive.Contains(pindexTest)) {
+ assert(pindexTest->nStatus & BLOCK_HAVE_DATA);
+ assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
if (pindexTest->nStatus & BLOCK_FAILED_MASK) {
// Candidate has an invalid ancestor, remove entire chain from the set.
if (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
@@ -1907,10 +1939,10 @@ static CBlockIndex* FindMostWorkChain() {
CBlockIndex *pindexFailed = pindexNew;
while (pindexTest != pindexFailed) {
pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
- setBlockIndexValid.erase(pindexFailed);
+ setBlockIndexCandidates.erase(pindexFailed);
pindexFailed = pindexFailed->pprev;
}
- setBlockIndexValid.erase(pindexTest);
+ setBlockIndexCandidates.erase(pindexTest);
fInvalidAncestor = true;
break;
}
@@ -1937,12 +1969,20 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
// Build list of new blocks to connect.
std::vector<CBlockIndex*> vpindexToConnect;
- vpindexToConnect.reserve(pindexMostWork->nHeight - (pindexFork ? pindexFork->nHeight : -1));
- CBlockIndex *pindexIter = pindexMostWork;
- while (pindexIter && pindexIter != pindexFork) {
+ bool fContinue = true;
+ int nHeight = pindexFork ? pindexFork->nHeight : -1;
+ while (fContinue && nHeight != pindexMostWork->nHeight) {
+ // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
+ // a few blocks along the way.
+ int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
+ vpindexToConnect.clear();
+ vpindexToConnect.reserve(nTargetHeight - nHeight);
+ CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
+ while (pindexIter && pindexIter->nHeight != nHeight) {
vpindexToConnect.push_back(pindexIter);
pindexIter = pindexIter->pprev;
}
+ nHeight = nTargetHeight;
// Connect new blocks.
BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
@@ -1953,27 +1993,30 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
InvalidChainFound(vpindexToConnect.back());
state = CValidationState();
fInvalidFound = true;
+ fContinue = false;
break;
} else {
// A system error occurred (disk space, database error, ...).
return false;
}
} else {
- // Delete all entries in setBlockIndexValid that are worse than our new current block.
+ // Delete all entries in setBlockIndexCandidates that are worse than our new current block.
// Note that we can't delete the current block itself, as we may need to return to it later in case a
// reorganization to a better block fails.
- std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexValid.begin();
- while (setBlockIndexValid.value_comp()(*it, chainActive.Tip())) {
- setBlockIndexValid.erase(it++);
+ std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
+ while (setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
+ setBlockIndexCandidates.erase(it++);
}
- // Either the current tip or a successor of it we're working towards is left in setBlockIndexValid.
- assert(!setBlockIndexValid.empty());
+ // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
+ assert(!setBlockIndexCandidates.empty());
if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
// We're in a better position than we were. Return temporarily to release the lock.
+ fContinue = false;
break;
}
}
}
+ }
// Callbacks/notifications for a new best chain.
if (fInvalidFound)
@@ -2032,7 +2075,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
return true;
}
-CBlockIndex* AddToBlockIndex(CBlockHeader& block)
+CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
{
// Check for duplicate
uint256 hash = block.GetHash();
@@ -2043,10 +2086,10 @@ CBlockIndex* AddToBlockIndex(CBlockHeader& block)
// Construct new block index object
CBlockIndex* pindexNew = new CBlockIndex(block);
assert(pindexNew);
- {
- LOCK(cs_nBlockSequenceId);
- pindexNew->nSequenceId = nBlockSequenceId++;
- }
+ // We assign the sequence id to blocks only when the full data is available,
+ // to avoid miners withholding blocks but broadcasting headers, to get a
+ // competitive advantage.
+ pindexNew->nSequenceId = 0;
BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
pindexNew->phashBlock = &((*mi).first);
BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
@@ -2058,6 +2101,11 @@ CBlockIndex* AddToBlockIndex(CBlockHeader& block)
}
pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWork();
pindexNew->RaiseValidity(BLOCK_VALID_TREE);
+ if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
+ pindexBestHeader = pindexNew;
+
+ // Ok if it fails, we'll download the header again next time.
+ pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew));
return pindexNew;
}
@@ -2066,30 +2114,45 @@ CBlockIndex* AddToBlockIndex(CBlockHeader& block)
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
{
pindexNew->nTx = block.vtx.size();
- if (pindexNew->pprev) {
- // Not the genesis block.
- if (pindexNew->pprev->nChainTx) {
- // This parent's block's total number transactions is known, so compute outs.
- pindexNew->nChainTx = pindexNew->pprev->nChainTx + pindexNew->nTx;
- } else {
- // The total number of transactions isn't known yet.
- // We will compute it when the block is connected.
- pindexNew->nChainTx = 0;
- }
- } else {
- // Genesis block.
- pindexNew->nChainTx = pindexNew->nTx;
- }
+ pindexNew->nChainTx = 0;
pindexNew->nFile = pos.nFile;
pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0;
pindexNew->nStatus |= BLOCK_HAVE_DATA;
+ pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
+ {
+ LOCK(cs_nBlockSequenceId);
+ pindexNew->nSequenceId = nBlockSequenceId++;
+ }
- if (pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS))
- setBlockIndexValid.insert(pindexNew);
-
- if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
- return state.Abort("Failed to write block index");
+ if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
+ // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
+ deque<CBlockIndex*> queue;
+ queue.push_back(pindexNew);
+
+ // Recursively process any descendant blocks that now may be eligible to be connected.
+ while (!queue.empty()) {
+ CBlockIndex *pindex = queue.front();
+ queue.pop_front();
+ pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
+ setBlockIndexCandidates.insert(pindex);
+ std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
+ while (range.first != range.second) {
+ std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
+ queue.push_back(it->second);
+ range.first++;
+ mapBlocksUnlinked.erase(it);
+ }
+ if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex)))
+ return state.Abort("Failed to write block index");
+ }
+ } else {
+ if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
+ mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
+ }
+ if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
+ return state.Abort("Failed to write block index");
+ }
return true;
}
@@ -2100,32 +2163,32 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
LOCK(cs_LastBlockFile);
- if (fKnown) {
- if (nLastBlockFile != pos.nFile) {
- nLastBlockFile = pos.nFile;
- infoLastBlockFile.SetNull();
- pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile);
- fUpdatedLast = true;
- }
- } else {
- while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
- LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString());
+ unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
+ if (vinfoBlockFile.size() <= nFile) {
+ vinfoBlockFile.resize(nFile + 1);
+ }
+
+ if (!fKnown) {
+ while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
+ LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
FlushBlockFile(true);
- nLastBlockFile++;
- infoLastBlockFile.SetNull();
- pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine
+ nFile++;
+ if (vinfoBlockFile.size() <= nFile) {
+ vinfoBlockFile.resize(nFile + 1);
+ }
fUpdatedLast = true;
}
- pos.nFile = nLastBlockFile;
- pos.nPos = infoLastBlockFile.nSize;
+ pos.nFile = nFile;
+ pos.nPos = vinfoBlockFile[nFile].nSize;
}
- infoLastBlockFile.nSize += nAddSize;
- infoLastBlockFile.AddBlock(nHeight, nTime);
+ nLastBlockFile = nFile;
+ vinfoBlockFile[nFile].nSize += nAddSize;
+ vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
if (!fKnown) {
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
- unsigned int nNewChunks = (infoLastBlockFile.nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
+ unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
if (nNewChunks > nOldChunks) {
if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
FILE *file = OpenBlockFile(pos);
@@ -2140,7 +2203,7 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
}
}
- if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
+ if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nFile]))
return state.Abort("Failed to write file info");
if (fUpdatedLast)
pblocktree->WriteLastBlockFile(nLastBlockFile);
@@ -2155,19 +2218,10 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
LOCK(cs_LastBlockFile);
unsigned int nNewSize;
- if (nFile == nLastBlockFile) {
- pos.nPos = infoLastBlockFile.nUndoSize;
- nNewSize = (infoLastBlockFile.nUndoSize += nAddSize);
- if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
- return state.Abort("Failed to write block info");
- } else {
- CBlockFileInfo info;
- if (!pblocktree->ReadBlockFileInfo(nFile, info))
- return state.Abort("Failed to read block info");
- pos.nPos = info.nUndoSize;
- nNewSize = (info.nUndoSize += nAddSize);
- if (!pblocktree->WriteBlockFileInfo(nFile, info))
- return state.Abort("Failed to write block info");
+ pos.nPos = vinfoBlockFile[nFile].nUndoSize;
+ nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
+ if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nLastBlockFile])) {
+ return state.Abort("Failed to write block info");
}
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
@@ -2205,12 +2259,31 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
{
- // These are checks that are independent of context
- // that can be verified before saving an orphan block.
+ // These are checks that are independent of context.
if (!CheckBlockHeader(block, state, fCheckPOW))
return false;
+ // Check the merkle root.
+ if (fCheckMerkleRoot) {
+ bool mutated;
+ uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
+ if (block.hashMerkleRoot != hashMerkleRoot2)
+ return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
+ REJECT_INVALID, "bad-txnmrklroot", true);
+
+ // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
+ // of transactions in a block without affecting the merkle root of a block,
+ // while still invalidating it.
+ if (mutated)
+ return state.DoS(100, error("CheckBlock() : duplicate transaction"),
+ REJECT_INVALID, "bad-txns-duplicate", true);
+ }
+
+ // All potential-corruption validation must be done before we do any
+ // transaction validation, as otherwise we may mark the header as invalid
+ // because we receive the wrong transactions for it.
+
// Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
return state.DoS(100, error("CheckBlock() : size limits failed"),
@@ -2230,15 +2303,6 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
if (!CheckTransaction(tx, state))
return error("CheckBlock() : CheckTransaction failed");
- // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
- // of transactions in a block without affecting the merkle root of a block,
- // while still invalidating it.
- bool mutated;
- uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
- if (mutated)
- return state.DoS(100, error("CheckBlock() : duplicate transaction"),
- REJECT_INVALID, "bad-txns-duplicate", true);
-
unsigned int nSigOps = 0;
BOOST_FOREACH(const CTransaction& tx, block.vtx)
{
@@ -2248,15 +2312,10 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true);
- // Check merkle root
- if (fCheckMerkleRoot && block.hashMerkleRoot != hashMerkleRoot2)
- return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
- REJECT_INVALID, "bad-txnmrklroot", true);
-
return true;
}
-bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
+bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
{
AssertLockHeld(cs_main);
// Check for duplicate
@@ -2264,26 +2323,13 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex
BlockMap::iterator miSelf = mapBlockIndex.find(hash);
CBlockIndex *pindex = NULL;
if (miSelf != mapBlockIndex.end()) {
+ // Block header is already known.
pindex = miSelf->second;
+ if (ppindex)
+ *ppindex = pindex;
if (pindex->nStatus & BLOCK_FAILED_MASK)
return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate");
- }
-
- CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
- if (pcheckpoint && block.hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
- {
- // Extra checks to prevent "fill up memory by spamming with bogus blocks"
- int64_t deltaTime = block.GetBlockTime() - pcheckpoint->GetBlockTime();
- if (deltaTime < 0)
- {
- return state.DoS(100, error("%s : block with timestamp before last checkpoint", __func__),
- REJECT_CHECKPOINT, "time-too-old");
- }
- if (!CheckMinWork(block.nBits, pcheckpoint->nBits, deltaTime))
- {
- return state.DoS(100, error("%s : block with too little proof-of-work", __func__),
- REJECT_INVALID, "bad-diffbits");
- }
+ return true;
}
// Get prev block index
@@ -2344,6 +2390,12 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
if (!AcceptBlockHeader(block, state, &pindex))
return false;
+ if (pindex->nStatus & BLOCK_HAVE_DATA) {
+ // TODO: deal better with duplicate blocks.
+ // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
+ return true;
+ }
+
if (!CheckBlock(block, state)) {
if (state.IsInvalid() && !state.CorruptionPossible()) {
pindex->nStatus |= BLOCK_FAILED_VALID;
@@ -2456,93 +2508,26 @@ void CBlockIndex::BuildSkip()
pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
}
-void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd)
-{
- AssertLockHeld(cs_main);
- // Filter out duplicate requests
- if (pindexBegin == pnode->pindexLastGetBlocksBegin && hashEnd == pnode->hashLastGetBlocksEnd)
- return;
- pnode->pindexLastGetBlocksBegin = pindexBegin;
- pnode->hashLastGetBlocksEnd = hashEnd;
-
- pnode->PushMessage("getblocks", chainActive.GetLocator(pindexBegin), hashEnd);
-}
-
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
{
- // Check for duplicate
- uint256 hash = pblock->GetHash();
-
- {
- LOCK(cs_main);
- if (mapBlockIndex.count(hash))
- return state.Invalid(error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString()), 0, "duplicate");
- if (mapOrphanBlocks.count(hash))
- return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString()), 0, "duplicate");
-
// Preliminary checks
- if (!CheckBlock(*pblock, state))
- return error("ProcessBlock() : CheckBlock FAILED");
+ bool checked = CheckBlock(*pblock, state);
- // If we don't already have its previous block (with full data), shunt it off to holding area until we get it
- BlockMap::iterator it = mapBlockIndex.find(pblock->hashPrevBlock);
- if (pblock->hashPrevBlock != 0 && (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA)))
{
- LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString());
-
- // Accept orphans as long as there is a node to request its parents from
- if (pfrom) {
- PruneOrphanBlocks();
- COrphanBlock* pblock2 = new COrphanBlock();
- {
- CDataStream ss(SER_DISK, CLIENT_VERSION);
- ss << *pblock;
- pblock2->vchBlock = std::vector<unsigned char>(ss.begin(), ss.end());
- }
- pblock2->hashBlock = hash;
- pblock2->hashPrev = pblock->hashPrevBlock;
- mapOrphanBlocks.insert(make_pair(hash, pblock2));
- mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrev, pblock2));
-
- // Ask this guy to fill in what we're missing
- PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(hash));
+ LOCK(cs_main);
+ MarkBlockAsReceived(pblock->GetHash());
+ if (!checked) {
+ return error("ProcessBlock() : CheckBlock FAILED");
}
- return true;
- }
- // Store to disk
- CBlockIndex *pindex = NULL;
- bool ret = AcceptBlock(*pblock, state, &pindex, dbp);
- if (!ret)
- return error("ProcessBlock() : AcceptBlock FAILED");
-
- // Recursively process any orphan blocks that depended on this one
- vector<uint256> vWorkQueue;
- vWorkQueue.push_back(hash);
- for (unsigned int i = 0; i < vWorkQueue.size(); i++)
- {
- uint256 hashPrev = vWorkQueue[i];
- for (multimap<uint256, COrphanBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
- mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
- ++mi)
- {
- CBlock block;
- {
- CDataStream ss(mi->second->vchBlock, SER_DISK, CLIENT_VERSION);
- ss >> block;
- }
- block.BuildMerkleTree();
- // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned)
- CValidationState stateDummy;
- CBlockIndex *pindexChild = NULL;
- if (AcceptBlock(block, stateDummy, &pindexChild))
- vWorkQueue.push_back(mi->second->hashBlock);
- mapOrphanBlocks.erase(mi->second->hashBlock);
- delete mi->second;
+ // Store to disk
+ CBlockIndex *pindex = NULL;
+ bool ret = AcceptBlock(*pblock, state, &pindex, dbp);
+ if (pindex && pfrom) {
+ mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
}
- mapOrphanBlocksByPrev.erase(hashPrev);
- }
-
+ if (!ret)
+ return error("ProcessBlock() : AcceptBlock FAILED");
}
if (!ActivateBestChain(state, pblock))
@@ -2808,20 +2793,44 @@ bool static LoadBlockIndexDB()
{
CBlockIndex* pindex = item.second;
pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + pindex->GetBlockWork();
- pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
- if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS))
- setBlockIndexValid.insert(pindex);
+ if (pindex->nStatus & BLOCK_HAVE_DATA) {
+ if (pindex->pprev) {
+ if (pindex->pprev->nChainTx) {
+ pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
+ } else {
+ pindex->nChainTx = 0;
+ mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
+ }
+ } else {
+ pindex->nChainTx = pindex->nTx;
+ }
+ }
+ if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
+ setBlockIndexCandidates.insert(pindex);
if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
pindexBestInvalid = pindex;
if (pindex->pprev)
pindex->BuildSkip();
+ if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
+ pindexBestHeader = pindex;
}
// Load block file info
pblocktree->ReadLastBlockFile(nLastBlockFile);
- LogPrintf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile);
- if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile))
- LogPrintf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString());
+ vinfoBlockFile.resize(nLastBlockFile + 1);
+ LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
+ for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
+ pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
+ }
+ LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
+ for (int nFile = nLastBlockFile + 1; true; nFile++) {
+ CBlockFileInfo info;
+ if (pblocktree->ReadBlockFileInfo(nFile, info)) {
+ vinfoBlockFile.push_back(info);
+ } else {
+ break;
+ }
+ }
// Check presence of blk files
LogPrintf("Checking all blk files are present...\n");
@@ -2836,7 +2845,7 @@ bool static LoadBlockIndexDB()
for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
{
CDiskBlockPos pos(*it, 0);
- if (!CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION)) {
+ if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
return false;
}
}
@@ -2952,7 +2961,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
void UnloadBlockIndex()
{
mapBlockIndex.clear();
- setBlockIndexValid.clear();
+ setBlockIndexCandidates.clear();
chainActive.SetTip(NULL);
pindexBestInvalid = NULL;
}
@@ -3075,21 +3084,14 @@ void PrintBlockTree()
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
{
+ // Map of disk positions for blocks with unknown parent (only used for reindex)
+ static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
int64_t nStart = GetTimeMillis();
int nLoaded = 0;
try {
// This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
- uint64_t nStartByte = 0;
- if (dbp) {
- // (try to) skip already indexed part
- CBlockFileInfo info;
- if (pblocktree->ReadBlockFileInfo(dbp->nFile, info)) {
- nStartByte = info.nSize;
- blkdat.Seek(info.nSize);
- }
- }
uint64_t nRewind = blkdat.GetPos();
while (!blkdat.eof()) {
boost::this_thread::interruption_point();
@@ -3117,21 +3119,57 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
try {
// read block
uint64_t nBlockPos = blkdat.GetPos();
+ if (dbp)
+ dbp->nPos = nBlockPos;
blkdat.SetLimit(nBlockPos + nSize);
+ blkdat.SetPos(nBlockPos);
CBlock block;
blkdat >> block;
nRewind = blkdat.GetPos();
- // process block
- if (nBlockPos >= nStartByte) {
+ // detect out of order blocks, and store them for later
+ uint256 hash = block.GetHash();
+ if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
+ LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
+ block.hashPrevBlock.ToString());
if (dbp)
- dbp->nPos = nBlockPos;
+ mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
+ continue;
+ }
+
+ // process in case the block isn't known yet
+ if (mapBlockIndex.count(hash) == 0) {
CValidationState state;
if (ProcessBlock(state, NULL, &block, dbp))
nLoaded++;
if (state.IsError())
break;
}
+
+ // Recursively process earlier encountered successors of this block
+ deque<uint256> queue;
+ queue.push_back(hash);
+ while (!queue.empty()) {
+ uint256 head = queue.front();
+ queue.pop_front();
+ std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
+ while (range.first != range.second) {
+ std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
+ if (ReadBlockFromDisk(block, it->second))
+ {
+ LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
+ head.ToString());
+ CValidationState dummy;
+ if (ProcessBlock(dummy, NULL, &block, &it->second))
+ {
+ nLoaded++;
+ queue.push_back(block.GetHash());
+ }
+ }
+ range.first++;
+ mapBlocksUnknownParent.erase(it);
+ }
+ }
} catch (std::exception &e) {
LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
}
@@ -3226,8 +3264,7 @@ bool static AlreadyHave(const CInv& inv)
pcoinsTip->HaveCoins(inv.hash);
}
case MSG_BLOCK:
- return mapBlockIndex.count(inv.hash) ||
- mapOrphanBlocks.count(inv.hash);
+ return mapBlockIndex.count(inv.hash);
}
// Don't know what it is, just say we already got one
return true;
@@ -3375,10 +3412,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return true;
}
- {
- LOCK(cs_main);
- State(pfrom->GetId())->nLastBlockProcess = GetTimeMicros();
- }
@@ -3587,6 +3620,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LOCK(cs_main);
+ std::vector<CInv> vToFetch;
+
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
{
const CInv &inv = vInv[nInv];
@@ -3597,19 +3632,30 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
bool fAlreadyHave = AlreadyHave(inv);
LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
- if (!fAlreadyHave) {
- if (!fImporting && !fReindex) {
- if (inv.type == MSG_BLOCK)
- AddBlockToQueue(pfrom->GetId(), inv.hash);
- else
- pfrom->AskFor(inv);
- }
- } else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
- PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(inv.hash));
- }
+ if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
+ pfrom->AskFor(inv);
- if (inv.type == MSG_BLOCK)
+ if (inv.type == MSG_BLOCK) {
UpdateBlockAvailability(pfrom->GetId(), inv.hash);
+ if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
+ // First request the headers preceeding the announced block. In the normal fully-synced
+ // case where a new block is announced that succeeds the current tip (no reorganization),
+ // there are no such headers.
+ // Secondly, and only when we are close to being synced, we request the announced block directly,
+ // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
+ // time the block arrives, the header chain leading up to it is already validated. Not
+ // doing this will result in the received block being rejected as an orphan in case it is
+ // not a direct successor.
+ pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
+ if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20) {
+ vToFetch.push_back(inv);
+ // Mark block as in flight already, even though the actual "getdata" message only goes out
+ // later (within the same cs_main lock, though).
+ MarkBlockAsInFlight(pfrom->GetId(), inv.hash);
+ }
+ LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
+ }
+ }
// Track requests for our stuff
g_signals.Inventory(inv.hash);
@@ -3619,6 +3665,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return error("send buffer size() = %u", pfrom->nSendSize);
}
}
+
+ if (!vToFetch.empty())
+ pfrom->PushMessage("getdata", vToFetch);
}
@@ -3706,8 +3755,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
vector<CBlock> vHeaders;
- int nLimit = 2000;
- LogPrint("net", "getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString());
+ int nLimit = MAX_HEADERS_RESULTS;
+ LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
for (; pindex; pindex = chainActive.Next(pindex))
{
vHeaders.push_back(pindex->GetBlockHeader());
@@ -3826,22 +3875,67 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
+ else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
+ {
+ std::vector<CBlockHeader> headers;
+
+ // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
+ unsigned int nCount = ReadCompactSize(vRecv);
+ if (nCount > MAX_HEADERS_RESULTS) {
+ Misbehaving(pfrom->GetId(), 20);
+ return error("headers message size = %u", nCount);
+ }
+ headers.resize(nCount);
+ for (unsigned int n = 0; n < nCount; n++) {
+ vRecv >> headers[n];
+ ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
+ }
+
+ LOCK(cs_main);
+
+ if (nCount == 0) {
+ // Nothing interesting. Stop asking this peers for more headers.
+ return true;
+ }
+
+ CBlockIndex *pindexLast = NULL;
+ BOOST_FOREACH(const CBlockHeader& header, headers) {
+ CValidationState state;
+ if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
+ Misbehaving(pfrom->GetId(), 20);
+ return error("non-continuous headers sequence");
+ }
+ if (!AcceptBlockHeader(header, state, &pindexLast)) {
+ int nDoS;
+ if (state.IsInvalid(nDoS)) {
+ if (nDoS > 0)
+ Misbehaving(pfrom->GetId(), nDoS);
+ return error("invalid header received");
+ }
+ }
+ }
+
+ if (pindexLast)
+ UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
+
+ if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
+ // Headers message had its maximum size; the peer may have more headers.
+ // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
+ // from there instead.
+ LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
+ pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0));
+ }
+ }
+
else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
{
CBlock block;
vRecv >> block;
- LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id);
-
CInv inv(MSG_BLOCK, block.GetHash());
- pfrom->AddInventoryKnown(inv);
+ LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
- {
- LOCK(cs_main);
- // Remember who we got this block from.
- mapBlockSource[inv.hash] = pfrom->GetId();
- MarkBlockAsReceived(inv.hash, pfrom->GetId());
- }
+ pfrom->AddInventoryKnown(inv);
CValidationState state;
ProcessBlock(state, pfrom, &block);
@@ -4323,9 +4417,18 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
state.rejects.clear();
// Start block sync
- if (pto->fStartSync && !fImporting && !fReindex) {
- pto->fStartSync = false;
- PushGetBlocks(pto, chainActive.Tip(), uint256(0));
+ if (pindexBestHeader == NULL)
+ pindexBestHeader = chainActive.Tip();
+ bool fFetch = !pto->fInbound || (pindexBestHeader && (state.pindexLastCommonBlock ? state.pindexLastCommonBlock->nHeight : 0) + 144 > pindexBestHeader->nHeight);
+ if (!state.fSyncStarted && !pto->fClient && fFetch && !fImporting && !fReindex) {
+ // Only actively request headers from a single peer, unless we're close to today.
+ if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
+ state.fSyncStarted = true;
+ nSyncStarted++;
+ CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
+ LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
+ pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0));
+ }
}
// Resend wallet transactions that haven't gotten in a block yet
@@ -4384,35 +4487,35 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
if (!vInv.empty())
pto->PushMessage("inv", vInv);
-
- // Detect stalled peers. Require that blocks are in flight, we haven't
- // received a (requested) block in one minute, and that all blocks are
- // in flight for over two minutes, since we first had a chance to
- // process an incoming block.
+ // Detect whether we're stalling
int64_t nNow = GetTimeMicros();
- if (!pto->fDisconnect && state.nBlocksInFlight &&
- state.nLastBlockReceive < state.nLastBlockProcess - BLOCK_DOWNLOAD_TIMEOUT*1000000 &&
- state.vBlocksInFlight.front().nTime < state.nLastBlockProcess - 2*BLOCK_DOWNLOAD_TIMEOUT*1000000) {
- LogPrintf("Peer %s is stalling block download, disconnecting\n", state.name);
+ if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
+ // Stalling only triggers when the block download window cannot move. During normal steady state,
+ // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
+ // should only happen during initial block download.
+ LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
pto->fDisconnect = true;
}
- // Update knowledge of peer's block availability.
- ProcessBlockAvailability(pto->GetId());
-
//
// Message: getdata (blocks)
//
vector<CInv> vGetData;
- while (!pto->fDisconnect && state.nBlocksToDownload && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
- uint256 hash = state.vBlocksToDownload.front();
- vGetData.push_back(CInv(MSG_BLOCK, hash));
- MarkBlockAsInFlight(pto->GetId(), hash);
- LogPrint("net", "Requesting block %s peer=%d\n", hash.ToString(), pto->id);
- if (vGetData.size() >= 1000)
- {
- pto->PushMessage("getdata", vGetData);
- vGetData.clear();
+ if (!pto->fDisconnect && !pto->fClient && fFetch && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
+ vector<CBlockIndex*> vToDownload;
+ NodeId staller = -1;
+ FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
+ BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
+ vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
+ MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), pindex);
+ LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
+ pindex->nHeight, pto->id);
+ }
+ if (state.nBlocksInFlight == 0 && staller != -1) {
+ if (State(staller)->nStallingSince == 0) {
+ State(staller)->nStallingSince = nNow;
+ LogPrint("net", "Stall started peer=%d\n", staller);
+ }
}
}
@@ -4447,7 +4550,7 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
{
// Open history file to append
CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
- if (!fileout)
+ if (fileout.IsNull())
return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");
// Write index header
@@ -4455,7 +4558,7 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
fileout << FLATDATA(Params().MessageStart()) << nSize;
// Write undo data
- long fileOutPos = ftell(fileout);
+ long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
return error("CBlockUndo::WriteToDisk : ftell failed");
pos.nPos = (unsigned int)fileOutPos;
@@ -4468,9 +4571,9 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
fileout << hasher.GetHash();
// Flush stdio buffers and commit to disk before returning
- fflush(fileout);
+ fflush(fileout.Get());
if (!IsInitialBlockDownload())
- FileCommit(fileout);
+ FileCommit(fileout.Get());
return true;
}
@@ -4479,7 +4582,7 @@ bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock
{
// Open history file to read
CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (!filein)
+ if (filein.IsNull())
return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");
// Read block
@@ -4519,12 +4622,6 @@ public:
delete (*it1).second;
mapBlockIndex.clear();
- // orphan blocks
- std::map<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocks.begin();
- for (; it2 != mapOrphanBlocks.end(); it2++)
- delete (*it2).second;
- mapOrphanBlocks.clear();
-
// orphan transactions
mapOrphanTransactions.clear();
mapOrphanTransactionsByPrev.clear();
diff --git a/src/main.h b/src/main.h
index 9f9401653e..1ef51918c5 100644
--- a/src/main.h
+++ b/src/main.h
@@ -73,9 +73,17 @@ static const int MAX_SCRIPTCHECK_THREADS = 16;
/** -par default (number of script-checking threads, 0 = auto) */
static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
/** Number of blocks that can be requested at any given time from a single peer. */
-static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 128;
-/** Timeout in seconds before considering a block download peer unresponsive. */
-static const unsigned int BLOCK_DOWNLOAD_TIMEOUT = 60;
+static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16;
+/** Timeout in seconds during which a peer must stall block download progress before being disconnected. */
+static const unsigned int BLOCK_STALLING_TIMEOUT = 2;
+/** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends
+ * less than this number, we reached their tip. Changing this value is a protocol upgrade. */
+static const unsigned int MAX_HEADERS_RESULTS = 2000;
+/** Size of the "block download window": how far ahead of our current height do we fetch?
+ * Larger windows tolerate larger download speed differences between peer, but increase the potential
+ * degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning
+ * harder). We'll probably want to make this a per-peer adaptive value at some point. */
+static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024;
/** "reject" message codes **/
static const unsigned char REJECT_MALFORMED = 0x01;
@@ -111,6 +119,9 @@ extern bool fIsBareMultisigStd;
extern unsigned int nCoinCacheSize;
extern CFeeRate minRelayTxFee;
+// Best header we've seen so far (used for getheaders queries' starting points).
+extern CBlockIndex *pindexBestHeader;
+
// Minimum disk space required - used in CheckDiskSpace()
static const uint64_t nMinDiskSpace = 52428800;
@@ -119,17 +130,17 @@ class CBlockTreeDB;
class CTxUndo;
class CScriptCheck;
class CValidationState;
-class CWalletInterface;
+class CValidationInterface;
struct CNodeStateStats;
struct CBlockTemplate;
/** Register a wallet to receive updates from core */
-void RegisterWallet(CWalletInterface* pwalletIn);
+void RegisterValidationInterface(CValidationInterface* pwalletIn);
/** Unregister a wallet from core */
-void UnregisterWallet(CWalletInterface* pwalletIn);
+void UnregisterValidationInterface(CValidationInterface* pwalletIn);
/** Unregister all wallets from core */
-void UnregisterAllWallets();
+void UnregisterAllValidationInterfaces();
/** Push an updated transaction to all registered wallets */
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL);
@@ -138,8 +149,6 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals);
/** Unregister a network node */
void UnregisterNodeSignals(CNodeSignals& nodeSignals);
-void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd);
-
/** Process an incoming block */
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
/** Check whether enough disk space is available for an incoming block */
@@ -194,6 +203,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
struct CNodeStateStats {
int nMisbehavior;
int nSyncHeight;
+ int nCommonHeight;
+ std::vector<int> vHeightInFlight;
};
struct CDiskTxPos : public CDiskBlockPos
@@ -440,9 +451,6 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
// Apply the effects of this block (with given index) on the UTXO set represented by coins
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);
-// Add this block to the block index, and if necessary, switch the active block chain to this
-bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos);
-
// Context-independent validity checks
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true);
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
@@ -450,7 +458,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = t
// Store block on disk
// if dbp is provided, the file is known to already reside on disk
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL);
-bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
+bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
@@ -633,17 +641,17 @@ public:
};
-class CWalletInterface {
+class CValidationInterface {
protected:
- virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) =0;
- virtual void EraseFromWallet(const uint256 &hash) =0;
- virtual void SetBestChain(const CBlockLocator &locator) =0;
- virtual void UpdatedTransaction(const uint256 &hash) =0;
- virtual void Inventory(const uint256 &hash) =0;
- virtual void ResendWalletTransactions() =0;
- friend void ::RegisterWallet(CWalletInterface*);
- friend void ::UnregisterWallet(CWalletInterface*);
- friend void ::UnregisterAllWallets();
+ virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {};
+ virtual void EraseFromWallet(const uint256 &hash) {};
+ virtual void SetBestChain(const CBlockLocator &locator) {};
+ virtual void UpdatedTransaction(const uint256 &hash) {};
+ virtual void Inventory(const uint256 &hash) {};
+ virtual void ResendWalletTransactions() {};
+ friend void ::RegisterValidationInterface(CValidationInterface*);
+ friend void ::UnregisterValidationInterface(CValidationInterface*);
+ friend void ::UnregisterAllValidationInterfaces();
};
#endif // BITCOIN_MAIN_H
diff --git a/src/miner.cpp b/src/miner.cpp
index 6a2718e403..eefccfd641 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -17,6 +17,7 @@
#endif
#include <boost/thread.hpp>
+#include <boost/tuple/tuple.hpp>
using namespace std;
diff --git a/src/net.cpp b/src/net.cpp
index dd5cb480cc..6cf64f51c3 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -73,7 +73,6 @@ map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {};
static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
-static CNode* pnodeSync = NULL;
uint64_t nLocalHostNonce = 0;
static std::vector<ListenSocket> vhListenSocket;
CAddrMan addrman;
@@ -519,10 +518,6 @@ void CNode::CloseSocketDisconnect()
TRY_LOCK(cs_vRecvMsg, lockRecv);
if (lockRecv)
vRecvMsg.clear();
-
- // if this was the sync node, we'll need a new one
- if (this == pnodeSync)
- pnodeSync = NULL;
}
void CNode::PushVersion()
@@ -615,7 +610,6 @@ void CNode::copyStats(CNodeStats &stats)
X(nSendBytes);
X(nRecvBytes);
X(fWhitelisted);
- stats.fSyncNode = (this == pnodeSync);
// It is common for nodes with good ping times to suddenly become lagged,
// due to a new block arriving or other large transfer.
@@ -1487,61 +1481,20 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu
}
-// for now, use a very simple selection metric: the node from which we received
-// most recently
-static int64_t NodeSyncScore(const CNode *pnode) {
- return pnode->nLastRecv;
-}
-
-void static StartSync(const vector<CNode*> &vNodes) {
- CNode *pnodeNewSync = NULL;
- int64_t nBestScore = 0;
-
- int nBestHeight = g_signals.GetHeight().get_value_or(0);
-
- // Iterate over all nodes
- BOOST_FOREACH(CNode* pnode, vNodes) {
- // check preconditions for allowing a sync
- if (!pnode->fClient && !pnode->fOneShot &&
- !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
- (pnode->nStartingHeight > (nBestHeight - 144)) &&
- (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
- // if ok, compare node's score with the best so far
- int64_t nScore = NodeSyncScore(pnode);
- if (pnodeNewSync == NULL || nScore > nBestScore) {
- pnodeNewSync = pnode;
- nBestScore = nScore;
- }
- }
- }
- // if a new sync candidate was found, start sync!
- if (pnodeNewSync) {
- pnodeNewSync->fStartSync = true;
- pnodeSync = pnodeNewSync;
- }
-}
-
void ThreadMessageHandler()
{
SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
while (true)
{
- bool fHaveSyncNode = false;
-
vector<CNode*> vNodesCopy;
{
LOCK(cs_vNodes);
vNodesCopy = vNodes;
BOOST_FOREACH(CNode* pnode, vNodesCopy) {
pnode->AddRef();
- if (pnode == pnodeSync)
- fHaveSyncNode = true;
}
}
- if (!fHaveSyncNode)
- StartSync(vNodesCopy);
-
// Poll the connected nodes for messages
CNode* pnodeTrickle = NULL;
if (!vNodesCopy.empty())
@@ -1976,7 +1929,7 @@ bool CAddrDB::Write(const CAddrMan& addr)
boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
FILE *file = fopen(pathTmp.string().c_str(), "wb");
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
- if (!fileout)
+ if (fileout.IsNull())
return error("%s : Failed to open file %s", __func__, pathTmp.string());
// Write and commit header, data
@@ -1986,7 +1939,7 @@ bool CAddrDB::Write(const CAddrMan& addr)
catch (std::exception &e) {
return error("%s : Serialize or I/O error - %s", __func__, e.what());
}
- FileCommit(fileout);
+ FileCommit(fileout.Get());
fileout.fclose();
// replace existing peers.dat, if any, with new peers.dat.XXXX
@@ -2001,7 +1954,7 @@ bool CAddrDB::Read(CAddrMan& addr)
// open input file, and associate with CAutoFile
FILE *file = fopen(pathAddr.string().c_str(), "rb");
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
- if (!filein)
+ if (filein.IsNull())
return error("%s : Failed to open file %s", __func__, pathAddr.string());
// use file size to size memory buffer
@@ -2078,10 +2031,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn
nSendSize = 0;
nSendOffset = 0;
hashContinue = 0;
- pindexLastGetBlocksBegin = 0;
- hashLastGetBlocksEnd = 0;
nStartingHeight = -1;
- fStartSync = false;
fGetAddr = false;
fRelayTxes = false;
setInventoryKnown.max_size(SendBufferSize() / 1000);
diff --git a/src/net.h b/src/net.h
index ad0a1df7e2..18da24183f 100644
--- a/src/net.h
+++ b/src/net.h
@@ -158,7 +158,6 @@ public:
int nStartingHeight;
uint64_t nSendBytes;
uint64_t nRecvBytes;
- bool fSyncNode;
bool fWhitelisted;
double dPingTime;
double dPingWait;
@@ -276,10 +275,7 @@ protected:
public:
uint256 hashContinue;
- CBlockIndex* pindexLastGetBlocksBegin;
- uint256 hashLastGetBlocksEnd;
int nStartingHeight;
- bool fStartSync;
// flood relay
std::vector<CAddress> vAddrToSend;
diff --git a/src/noui.cpp b/src/noui.cpp
index f786a20db5..8f3b0275b0 100644
--- a/src/noui.cpp
+++ b/src/noui.cpp
@@ -14,6 +14,9 @@
static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
{
+ bool fSecure = style & CClientUIInterface::SECURE;
+ style &= ~CClientUIInterface::SECURE;
+
std::string strCaption;
// Check for usage of predefined caption
switch (style) {
@@ -30,7 +33,8 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str
strCaption += caption; // Use supplied caption (can be empty)
}
- LogPrintf("%s: %s\n", strCaption, message);
+ if (!fSecure)
+ LogPrintf("%s: %s\n", strCaption, message);
fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str());
return false;
}
diff --git a/src/pow.cpp b/src/pow.cpp
index d50222849c..75fbfc6a6d 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -98,39 +98,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
return true;
}
-//
-// true if nBits is greater than the minimum amount of work that could
-// possibly be required deltaTime after minimum work required was nBase
-//
-bool CheckMinWork(unsigned int nBits, unsigned int nBase, int64_t deltaTime)
-{
- bool fOverflow = false;
- uint256 bnNewBlock;
- bnNewBlock.SetCompact(nBits, NULL, &fOverflow);
- if (fOverflow)
- return false;
-
- const uint256 &bnLimit = Params().ProofOfWorkLimit();
- // Testnet has min-difficulty blocks
- // after Params().TargetSpacing()*2 time between blocks:
- if (Params().AllowMinDifficultyBlocks() && deltaTime > Params().TargetSpacing()*2)
- return bnNewBlock <= bnLimit;
-
- uint256 bnResult;
- bnResult.SetCompact(nBase);
- while (deltaTime > 0 && bnResult < bnLimit)
- {
- // Maximum 400% adjustment...
- bnResult *= 4;
- // ... in best-case exactly 4-times-normal target time
- deltaTime -= Params().TargetTimespan()*4;
- }
- if (bnResult > bnLimit)
- bnResult = bnLimit;
-
- return bnNewBlock <= bnResult;
-}
-
void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
{
pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
diff --git a/src/pow.h b/src/pow.h
index 5d91108ac4..233d1f3795 100644
--- a/src/pow.h
+++ b/src/pow.h
@@ -16,8 +16,6 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
-/** Check the work is more than the minimum a received block needs, without knowing its direct parent */
-bool CheckMinWork(unsigned int nBits, unsigned int nBase, int64_t deltaTime);
void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev);
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 8a945606dc..f0471c32f9 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -665,7 +665,7 @@ void BitcoinGUI::setNumBlocks(int count)
QDateTime currentDate = QDateTime::currentDateTime();
int secs = lastBlockDate.secsTo(currentDate);
- tooltip = tr("Processed %1 blocks of transaction history.").arg(count);
+ tooltip = tr("Processed %n blocks of transaction history.", "", count);
// Set icon state: spinning if catching up, tick otherwise
if(secs < 90*60)
@@ -992,6 +992,9 @@ void BitcoinGUI::showProgress(const QString &title, int nProgress)
static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
{
bool modal = (style & CClientUIInterface::MODAL);
+ // The SECURE flag has no effect in the Qt GUI.
+ // bool secure = (style & CClientUIInterface::SECURE);
+ style &= ~CClientUIInterface::SECURE;
bool ret = false;
// In case of modal message, use blocking connection to wait for user to click a button
QMetaObject::invokeMethod(gui, "message",
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 25c811183f..1073b6a472 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -22,11 +22,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"It is also recommended to set alertnotify so you are notified of problems;\n"
"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"(default: 1, 1 = keep tx meta data e.g. account owner and payment request "
-"information, 2 = drop tx meta data)"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!"
-"3DES:@STRENGTH)"),
+"(1 = keep tx meta data e.g. account owner and payment request information, 2 "
+"= drop tx meta data)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"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 "
@@ -49,7 +46,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Continuously rate-limit free transactions to <n>*1000 bytes per minute "
-"(default:15)"),
+"(default:%u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Create new files with system default permissions, instead of umask 077 (only "
"effective with disabled wallet functionality)"),
@@ -75,9 +72,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Unsupported argument -socks found. Setting SOCKS version isn't "
"possible anymore, only SOCKS5 proxies are supported."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Execute command when a network tx respends wallet tx input (%s=respend TxID, "
-"%t=wallet TxID)"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Execute command when a relevant alert is received or we see a really long "
"fork (%s in cmd is replaced by message)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -94,22 +88,24 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"creation (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Flush database activity from memory pool to disk log every <n> megabytes "
-"(default: 100)"),
+"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"How thorough the block verification of -checkblocks is (0-4, default: 3)"),
+"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"If paytxfee is not set, include enough fee so transactions are confirmed on "
-"average within n blocks (default: 1)"),
+"average within n blocks (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"In this mode -genproclimit controls how many blocks are generated "
"immediately."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)"),
+"Log transaction priority and fee per kB when mining blocks (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Maintain a full transaction index, used by the getrawtransaction rpc call "
+"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Number of seconds to keep misbehaving peers from reconnecting (default: "
-"86400)"),
+"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Output debugging information (default: 0, supplying <category> is optional)"),
+"Output debugging information (default: %u, supplying <category> is optional)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Query for peer addresses via DNS lookup, if low on addresses (default: 1 "
"unless -connect)"),
@@ -120,7 +116,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"leave that many cores free, default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set the processor limit for when generation is on (-1 = unlimited, default: "
-"-1)"),
+"%d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"This is a pre-release test build - use at your own risk - do not use for "
"mining or merchant applications"),
@@ -132,8 +128,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to %s on this computer. Bitcoin Core is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -"
-"proxy)"),
+"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
+"%s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -paytxfee is set very high! This is the transaction fee you will "
"pay if you send a transaction."),
@@ -154,19 +150,20 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect "
"you should restore from a backup."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Whitelist peers connecting from the given netmask or ip. Can be specified "
-"multiple times."),
+"Whitelist peers connecting from the given netmask or IP address. Can be "
+"specified multiple times."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"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"),
+QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "(default: wallet.dat)"),
QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
@@ -182,7 +179,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Develo
QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"),
QT_TRANSLATE_NOOP("bitcoin-core", "Could not parse -rpcbind value %s as network address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Disable safemode, override a real safe mode event (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Disable safemode, override a real safe mode event (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"),
QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"),
@@ -201,13 +198,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: 0)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: 0)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 288, 0 = all)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"),
QT_TRANSLATE_NOOP("bitcoin-core", "If <category> is not supplied, output all debugging information."),
QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong datadir for network?"),
QT_TRANSLATE_NOOP("bitcoin-core", "Information"),
QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin Core is shutting down."),
@@ -222,61 +219,60 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable blocks in memory (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: 50000)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Log transaction priority and fee per kB when mining blocks (default: 0)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Maintain a full transaction index (default: 0)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Print block on startup, if found in block index"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Print block tree on startup (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Print block tree on startup (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Randomly drop 1 of every <n> network messages"),
QT_TRANSLATE_NOOP("bitcoin-core", "Randomly fuzz 1 of every <n> network messages"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: 1)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Run a thread to flush wallet periodically (default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Run a thread to flush wallet periodically (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: 0)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: 4)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout in milliseconds (default: 5000)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout in milliseconds (minimum: 1, default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: 1)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
QT_TRANSLATE_NOOP("bitcoin-core", "This is intended for regression testing tools and app development."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
@@ -285,7 +281,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind r
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
index 7f28209c9a..898df2b080 100644
--- a/src/qt/forms/rpcconsole.ui
+++ b/src/qt/forms/rpcconsole.ui
@@ -836,29 +836,6 @@
</property>
</widget>
</item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_25">
- <property name="text">
- <string>Sync Node</string>
- </property>
- </widget>
- </item>
- <item row="4" column="2">
- <widget class="QLabel" name="peerSyncNode">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
<item row="5" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index d469c9a0bd..7618bff69d 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -215,10 +215,10 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable
{
ui->freeSpace->setText("");
} else {
- QString freeString = QString::number(bytesAvailable/GB_BYTES) + tr("GB of free space available");
+ QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES);
if(bytesAvailable < BLOCK_CHAIN_SIZE)
{
- freeString += " " + tr("(of %1GB needed)").arg(BLOCK_CHAIN_SIZE/GB_BYTES);
+ freeString += " " + tr("(of %n GB needed)", "", BLOCK_CHAIN_SIZE/GB_BYTES);
ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
} else {
ui->freeSpace->setStyleSheet("");
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 5c3abef2e7..df285441e1 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -286,27 +286,27 @@
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+327"/>
+ <location filename="../bitcoingui.cpp" line="+309"/>
<source>Sign &amp;message...</source>
<translation>Sign &amp;message...</translation>
</message>
<message>
- <location line="+348"/>
+ <location line="+339"/>
<source>Synchronizing with network...</source>
<translation>Synchronizing with network...</translation>
</message>
<message>
- <location line="-420"/>
+ <location line="-405"/>
<source>&amp;Overview</source>
<translation>&amp;Overview</translation>
</message>
<message>
- <location line="-142"/>
+ <location line="-129"/>
<source>Node</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+143"/>
+ <location line="+130"/>
<source>Show general overview of wallet</source>
<translation>Show general overview of wallet</translation>
</message>
@@ -331,7 +331,7 @@
<translation>Quit application</translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+7"/>
<location line="+2"/>
<source>About &amp;Qt</source>
<translation>About &amp;Qt</translation>
@@ -347,7 +347,7 @@
<translation>&amp;Options...</translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+6"/>
<source>&amp;Encrypt Wallet...</source>
<translation>&amp;Encrypt Wallet...</translation>
</message>
@@ -377,13 +377,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+175"/>
- <location line="+5"/>
+ <location line="+172"/>
<source>Bitcoin Core client</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+158"/>
+ <location line="+157"/>
<source>Importing blocks from disk...</source>
<translation>Importing blocks from disk...</translation>
</message>
@@ -393,17 +392,17 @@
<translation>Reindexing blocks on disk...</translation>
</message>
<message>
- <location line="-418"/>
+ <location line="-403"/>
<source>Send coins to a Bitcoin address</source>
<translation>Send coins to a Bitcoin address</translation>
</message>
<message>
- <location line="+49"/>
+ <location line="+46"/>
<source>Modify configuration options for Bitcoin</source>
<translation>Modify configuration options for Bitcoin</translation>
</message>
<message>
- <location line="+12"/>
+ <location line="+9"/>
<source>Backup wallet to another location</source>
<translation>Backup wallet to another location</translation>
</message>
@@ -428,17 +427,17 @@
<translation>&amp;Verify message...</translation>
</message>
<message>
- <location line="+446"/>
+ <location line="+437"/>
<source>Bitcoin</source>
<translation>Bitcoin</translation>
</message>
<message>
- <location line="-664"/>
+ <location line="-636"/>
<source>Wallet</source>
<translation>Wallet</translation>
</message>
<message>
- <location line="+151"/>
+ <location line="+138"/>
<source>&amp;Send</source>
<translation>&amp;Send</translation>
</message>
@@ -448,13 +447,12 @@
<translation>&amp;Receive</translation>
</message>
<message>
- <location line="+33"/>
+ <location line="+30"/>
<source>Show information about Bitcoin Core</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+13"/>
- <location line="+2"/>
+ <location line="+12"/>
<source>&amp;Show / Hide</source>
<translation>&amp;Show / Hide</translation>
</message>
@@ -499,29 +497,22 @@
<translation>Tabs toolbar</translation>
</message>
<message>
- <location line="-289"/>
- <location line="+393"/>
- <source>[testnet]</source>
- <translation>[testnet]</translation>
- </message>
- <message>
- <location line="-418"/>
+ <location line="-295"/>
<source>Bitcoin Core</source>
<translation type="unfinished">Bitcoin Core</translation>
</message>
<message>
- <location line="+168"/>
+ <location line="+155"/>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+29"/>
- <location line="+2"/>
+ <location line="+28"/>
<source>&amp;About Bitcoin Core</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+35"/>
+ <location line="+32"/>
<source>Show the list of used sending addresses and labels</source>
<translation type="unfinished"></translation>
</message>
@@ -546,7 +537,7 @@
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="+316"/>
+ <location line="+307"/>
<source>%n active connection(s) to Bitcoin network</source>
<translation>
<numerusform>%n active connection to Bitcoin network</numerusform>
@@ -558,13 +549,8 @@
<source>No block source available...</source>
<translation>No block source available...</translation>
</message>
- <message>
- <location line="+10"/>
- <source>Processed %1 blocks of transaction history.</source>
- <translation>Processed %1 blocks of transaction history.</translation>
- </message>
<message numerus="yes">
- <location line="+26"/>
+ <location line="+36"/>
<source>%n hour(s)</source>
<translation>
<numerusform>%n hour</numerusform>
@@ -636,8 +622,16 @@
<source>Up to date</source>
<translation>Up to date</translation>
</message>
+ <message numerus="yes">
+ <location line="-5"/>
+ <source>Processed %n blocks of transaction history.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <location line="+44"/>
+ <location line="+49"/>
<source>Catching up...</source>
<translation>Catching up...</translation>
</message>
@@ -1172,15 +1166,21 @@ Address: %4
<source>Error</source>
<translation>Error</translation>
</message>
- <message>
+ <message numerus="yes">
<location line="+9"/>
- <source>GB of free space available</source>
- <translation>GB of free space available</translation>
+ <source>%n GB of free space available</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
+ <message numerus="yes">
<location line="+3"/>
- <source>(of %1GB needed)</source>
- <translation>(of %1GB needed)</translation>
+ <source>(of %n GB needed)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
</context>
<context>
@@ -1813,12 +1813,11 @@ Address: %4
<location line="+23"/>
<location line="+23"/>
<location line="+23"/>
- <location line="+23"/>
<source>N/A</source>
<translation>N/A</translation>
</message>
<message>
- <location line="-990"/>
+ <location line="-967"/>
<source>Client version</source>
<translation>Client version</translation>
</message>
@@ -1921,11 +1920,6 @@ Address: %4
</message>
<message>
<location line="+23"/>
- <source>Sync Node</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+23"/>
<source>Starting Height</source>
<translation type="unfinished"></translation>
</message>
@@ -1970,7 +1964,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-764"/>
+ <location line="-741"/>
<source>Last block time</source>
<translation>Last block time</translation>
</message>
@@ -2086,17 +2080,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Yes</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+0"/>
- <source>No</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+12"/>
+ <location line="+13"/>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
@@ -2853,7 +2837,7 @@ Address: %4
<context>
<name>SplashScreen</name>
<message>
- <location filename="../splashscreen.cpp" line="+34"/>
+ <location filename="../splashscreen.cpp" line="+35"/>
<source>Bitcoin Core</source>
<translation type="unfinished">Bitcoin Core</translation>
</message>
@@ -2863,7 +2847,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
+ <location filename="../networkstyle.cpp" line="+19"/>
<source>[testnet]</source>
<translation>[testnet]</translation>
</message>
@@ -3418,7 +3402,7 @@ Address: %4
<context>
<name>UnitDisplayStatusBarControl</name>
<message>
- <location filename="../bitcoingui.cpp" line="+103"/>
+ <location filename="../bitcoingui.cpp" line="+106"/>
<source>Unit to show amounts in. Click to select another unit.</source>
<translation type="unfinished"></translation>
</message>
@@ -3485,62 +3469,27 @@ Address: %4
<context>
<name>bitcoin-core</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="+240"/>
+ <location filename="../bitcoinstrings.cpp" line="+236"/>
<source>Options:</source>
<translation>Options:</translation>
</message>
<message>
- <location line="+28"/>
- <source>Specify configuration file (default: bitcoin.conf)</source>
- <translation>Specify configuration file (default: bitcoin.conf)</translation>
- </message>
- <message>
- <location line="+3"/>
- <source>Specify pid file (default: bitcoind.pid)</source>
- <translation>Specify pid file (default: bitcoind.pid)</translation>
- </message>
- <message>
- <location line="-1"/>
+ <location line="+30"/>
<source>Specify data directory</source>
<translation>Specify data directory</translation>
</message>
<message>
- <location line="-44"/>
- <source>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</source>
- <translation>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</translation>
- </message>
- <message>
- <location line="+6"/>
- <source>Maintain at most &lt;n&gt; connections to peers (default: 125)</source>
- <translation>Maintain at most &lt;n&gt; connections to peers (default: 125)</translation>
- </message>
- <message>
- <location line="-53"/>
+ <location line="-90"/>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
<translation>Connect to a node to retrieve peer addresses, and disconnect</translation>
</message>
<message>
- <location line="+94"/>
+ <location line="+93"/>
<source>Specify your own public address</source>
<translation>Specify your own public address</translation>
</message>
<message>
- <location line="+6"/>
- <source>Threshold for disconnecting misbehaving peers (default: 100)</source>
- <translation>Threshold for disconnecting misbehaving peers (default: 100)</translation>
- </message>
- <message>
- <location line="-171"/>
- <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
- <translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation>
- </message>
- <message>
- <location line="-2"/>
- <source>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332 or testnet: 18332)</source>
- <translation>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332 or testnet: 18332)</translation>
- </message>
- <message>
- <location line="+59"/>
+ <location line="-108"/>
<source>Accept command line and JSON-RPC commands</source>
<translation>Accept command line and JSON-RPC commands</translation>
</message>
@@ -3560,7 +3509,7 @@ Address: %4
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
<message>
- <location line="-154"/>
+ <location line="-150"/>
<source>%s, you must set a rpcpassword in the configuration file:
%s
It is recommended you use the following random password:
@@ -3585,22 +3534,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</translation>
</message>
<message>
- <location line="+15"/>
- <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+10"/>
+ <location line="+22"/>
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
<translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation>
</message>
<message>
- <location line="+13"/>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default:15)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+6"/>
+ <location line="+19"/>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation type="unfinished"></translation>
</message>
@@ -3620,37 +3559,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</translation>
</message>
<message>
- <location line="+12"/>
+ <location line="+9"/>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation>
</message>
<message>
- <location line="+12"/>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: 100)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
- <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+5"/>
+ <location line="+20"/>
<source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+15"/>
+ <location line="+17"/>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+6"/>
<source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
<translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation>
</message>
@@ -3660,12 +3584,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+6"/>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</translation>
</message>
@@ -3690,13 +3609,13 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</translation>
</message>
<message>
- <location line="+10"/>
- <source>(default: 1)</source>
+ <location line="+4"/>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>(default: wallet.dat)</source>
+ <location line="+7"/>
+ <source>(default: 1)</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3705,7 +3624,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+7"/>
<source>Attempt to recover private keys from a corrupt wallet.dat</source>
<translation>Attempt to recover private keys from a corrupt wallet.dat</translation>
</message>
@@ -3735,12 +3654,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Disable safemode, override a real safe mode event (default: 0)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+2"/>
<source>Discover own IP address (default: 1 when listening and no -externalip)</source>
<translation>Discover own IP address (default: 1 when listening and no -externalip)</translation>
</message>
@@ -3795,22 +3709,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Failed to listen on any port. Use -listen=0 if you want this.</translation>
</message>
<message>
- <location line="+2"/>
- <source>Force safe mode (default: 0)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Generate coins (default: 0)</source>
- <translation>Generate coins (default: 0)</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>How many blocks to check at startup (default: 288, 0 = all)</source>
- <translation>How many blocks to check at startup (default: 288, 0 = all)</translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+5"/>
<source>If &lt;category&gt; is not supplied, output all debugging information.</source>
<translation type="unfinished"></translation>
</message>
@@ -3830,7 +3729,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+22"/>
+ <location line="+21"/>
<source>Not enough file descriptors available.</source>
<translation>Not enough file descriptors available.</translation>
</message>
@@ -3840,12 +3739,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Prepend debug output with timestamp (default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+7"/>
+ <location line="+10"/>
<source>Rebuild block chain index from current blk000??.dat files</source>
<translation>Rebuild block chain index from current blk000??.dat files</translation>
</message>
@@ -3860,32 +3754,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Set the number of threads to service RPC calls (default: 4)</source>
- <translation>Set the number of threads to service RPC calls (default: 4)</translation>
- </message>
- <message>
- <location line="+9"/>
+ <location line="+11"/>
<source>Specify wallet file (within data directory)</source>
<translation>Specify wallet file (within data directory)</translation>
</message>
<message>
- <location line="+2"/>
- <source>Spend unconfirmed change when sending transactions (default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Stop running after importing blocks from disk (default: 0)</source>
+ <location line="+6"/>
+ <source>This is intended for regression testing tools and app development.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>This is intended for regression testing tools and app development.</source>
+ <location line="+10"/>
+ <source>Use UPnP to map the listening port (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+14"/>
+ <location line="+4"/>
<source>Verifying blocks...</source>
<translation>Verifying blocks...</translation>
</message>
@@ -3910,17 +3794,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>You need to rebuild the database using -reindex to change -txindex</translation>
</message>
<message>
- <location line="-92"/>
+ <location line="-91"/>
<source>Imports blocks from external blk000??.dat file</source>
<translation>Imports blocks from external blk000??.dat file</translation>
</message>
<message>
- <location line="-185"/>
- <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+6"/>
+ <location line="-179"/>
<source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; 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</source>
<translation type="unfinished"></translation>
</message>
@@ -3945,7 +3824,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+3"/>
+ <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default:%u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation type="unfinished"></translation>
</message>
@@ -3966,11 +3850,6 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</message>
<message>
<location line="+3"/>
- <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
<source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
<translation>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</translation>
</message>
@@ -3985,17 +3864,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
- <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+11"/>
- <source>Output debugging information (default: 0, supplying &lt;category&gt; is optional)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+23"/>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation type="unfinished"></translation>
</message>
@@ -4015,22 +3884,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+16"/>
- <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+19"/>
<source>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</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
- <source>Always query for peer addresses via DNS lookup (default: 0)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+6"/>
+ <location line="+17"/>
<source>Cannot resolve -whitebind address: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -4065,12 +3924,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
- <source>Include IP addresses in debug output (default: 0)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+9"/>
<source>Information</source>
<translation>Information</translation>
</message>
@@ -4110,32 +3964,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: 50000)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+5"/>
- <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Maintain a full transaction index (default: 0)</source>
- <translation>Maintain a full transaction index (default: 0)</translation>
- </message>
- <message>
- <location line="+2"/>
- <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: 5000)</source>
- <translation>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: 5000)</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: 1000)</source>
- <translation>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: 1000)</translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+10"/>
<source>Need to specify a port with -whitebind: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -4145,22 +3974,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Only accept block chain matching built-in checkpoints (default: 1)</source>
- <translation>Only accept block chain matching built-in checkpoints (default: 1)</translation>
- </message>
- <message>
- <location line="+5"/>
+ <location line="+7"/>
<source>Print block on startup, if found in block index</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Print block tree on startup (default: 0)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+2"/>
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
<translation type="unfinished"></translation>
</message>
@@ -4180,37 +3999,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Relay and mine data carrier transactions (default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Relay non-P2SH multisig (default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
- <source>Run a thread to flush wallet periodically (default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+8"/>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Send trace/debug info to console instead of debug.log file</translation>
</message>
<message>
- <location line="+6"/>
- <source>Set minimum block size in bytes (default: 0)</source>
- <translation>Set minimum block size in bytes (default: 0)</translation>
- </message>
- <message>
- <location line="+2"/>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+9"/>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation type="unfinished"></translation>
</message>
@@ -4225,12 +4019,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Signing transaction failed</translation>
</message>
<message>
- <location line="+2"/>
- <source>Specify connection timeout in milliseconds (default: 5000)</source>
- <translation>Specify connection timeout in milliseconds (default: 5000)</translation>
- </message>
- <message>
- <location line="+8"/>
+ <location line="+10"/>
<source>This is experimental software.</source>
<translation type="unfinished"></translation>
</message>
@@ -4255,12 +4044,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>Use UPnP to map the listening port (default: 0)</source>
- <translation>Use UPnP to map the listening port (default: 0)</translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+5"/>
<source>Use UPnP to map the listening port (default: 1 when listening)</source>
<translation>Use UPnP to map the listening port (default: 1 when listening)</translation>
</message>
@@ -4315,22 +4099,17 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-155"/>
+ <location line="-157"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation>
</message>
<message>
- <location line="+200"/>
+ <location line="+202"/>
<source>Upgrade wallet to latest format</source>
<translation>Upgrade wallet to latest format</translation>
</message>
<message>
- <location line="-26"/>
- <source>Set key pool size to &lt;n&gt; (default: 100)</source>
- <translation>Set key pool size to &lt;n&gt; (default: 100)</translation>
- </message>
- <message>
- <location line="-8"/>
+ <location line="-34"/>
<source>Rescan the block chain for missing wallet transactions</source>
<translation>Rescan the block chain for missing wallet transactions</translation>
</message>
@@ -4340,52 +4119,252 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Use OpenSSL (https) for JSON-RPC connections</translation>
</message>
<message>
- <location line="-30"/>
- <source>Server certificate file (default: server.cert)</source>
- <translation>Server certificate file (default: server.cert)</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Server private key (default: server.pem)</source>
- <translation>Server private key (default: server.pem)</translation>
- </message>
- <message>
- <location line="+18"/>
+ <location line="-11"/>
<source>This help message</source>
<translation>This help message</translation>
</message>
<message>
- <location line="-108"/>
+ <location line="-107"/>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
<translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
</message>
<message>
- <location line="+59"/>
+ <location line="+60"/>
<source>Loading addresses...</source>
<translation>Loading addresses...</translation>
</message>
<message>
- <location line="-33"/>
+ <location line="-34"/>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Error loading wallet.dat: Wallet corrupted</translation>
</message>
<message>
- <location line="-1"/>
+ <location line="-167"/>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+65"/>
+ <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Set the processor limit for when generation is on (-1 = unlimited, default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>(default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Disable safemode, override a real safe mode event (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
<source>Error loading wallet.dat</source>
<translation>Error loading wallet.dat</translation>
</message>
<message>
- <location line="+23"/>
+ <location line="+11"/>
+ <source>Force safe mode (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Generate coins (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
<source>Invalid -proxy address: &apos;%s&apos;</source>
<translation>Invalid -proxy address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+69"/>
+ <location line="+9"/>
+ <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Run a thread to flush wallet periodically (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Server certificate file (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Server private key (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Specify configuration file (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Specify pid file (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Stop running after importing blocks from disk (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
<source>Unknown network specified in -onlynet: &apos;%s&apos;</source>
<translation>Unknown network specified in -onlynet: &apos;%s&apos;</translation>
</message>
<message>
- <location line="-112"/>
+ <location line="-111"/>
<source>Cannot resolve -bind address: &apos;%s&apos;</source>
<translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
</message>
@@ -4410,22 +4389,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Insufficient funds</translation>
</message>
<message>
- <location line="+14"/>
+ <location line="+15"/>
<source>Loading block index...</source>
<translation>Loading block index...</translation>
</message>
<message>
- <location line="-61"/>
+ <location line="-62"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation>Add a node to connect to and attempt to keep the connection open</translation>
</message>
<message>
- <location line="+62"/>
+ <location line="+63"/>
<source>Loading wallet...</source>
<translation>Loading wallet...</translation>
</message>
<message>
- <location line="-57"/>
+ <location line="-58"/>
<source>Cannot downgrade wallet</source>
<translation>Cannot downgrade wallet</translation>
</message>
@@ -4435,22 +4414,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Cannot write default address</translation>
</message>
<message>
- <location line="+77"/>
+ <location line="+76"/>
<source>Rescanning...</source>
<translation>Rescanning...</translation>
</message>
<message>
- <location line="-64"/>
+ <location line="-63"/>
<source>Done loading</source>
<translation>Done loading</translation>
</message>
<message>
- <location line="+91"/>
+ <location line="+90"/>
<source>To use the %s option</source>
<translation>To use the %s option</translation>
</message>
<message>
- <location line="-83"/>
+ <location line="-82"/>
<source>Error</source>
<translation>Error</translation>
</message>
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 8129353d4b..2d2d448b49 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -611,7 +611,6 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
ui->peerHeight->setText(QString("%1").arg(stats->nodeStats.nStartingHeight));
- ui->peerSyncNode->setText(stats->nodeStats.fSyncNode ? tr("Yes") : tr("No"));
// This check fails for example if the lock was busy and
// nodeStateStats couldn't be fetched.
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index 24175215bf..5beac0512a 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -445,6 +445,7 @@ Value getblockchaininfo(const Array& params, bool fHelp)
"{\n"
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
" \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
+ " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
" \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
" \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
" \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
@@ -458,6 +459,7 @@ Value getblockchaininfo(const Array& params, bool fHelp)
Object obj;
obj.push_back(Pair("chain", Params().NetworkIDString()));
obj.push_back(Pair("blocks", (int)chainActive.Height()));
+ obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip())));
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index bc19d1372a..12dcd5b540 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -97,7 +97,12 @@ Value getpeerinfo(const Array& params, bool fHelp)
" \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
" \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
" \"banscore\": n, (numeric) The ban score\n"
- " \"syncnode\": true|false (boolean) if sync node\n"
+ " \"synced_headers\": n, (numeric) The last header we have in common with this peer\n"
+ " \"synced_blocks\": n, (numeric) The last block we have in common with this peer\n"
+ " \"inflight\": [\n"
+ " n, (numeric) The heights of blocks we're currently asking from this peer\n"
+ " ...\n"
+ " ]\n"
" }\n"
" ,...\n"
"]\n"
@@ -137,9 +142,14 @@ Value getpeerinfo(const Array& params, bool fHelp)
obj.push_back(Pair("startingheight", stats.nStartingHeight));
if (fStateStats) {
obj.push_back(Pair("banscore", statestats.nMisbehavior));
- obj.push_back(Pair("syncheight", statestats.nSyncHeight));
+ obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
+ obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
+ Array heights;
+ BOOST_FOREACH(int height, statestats.vHeightInFlight) {
+ heights.push_back(height);
+ }
+ obj.push_back(Pair("inflight", heights));
}
- obj.push_back(Pair("syncnode", stats.fSyncNode));
obj.push_back(Pair("whitelisted", stats.fWhitelisted));
ret.push_back(obj);
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 1a41344da5..9668c78831 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -581,7 +581,7 @@ void StartRPCThreads()
strWhatAmI,
GetConfigFile().string(),
EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)),
- "", CClientUIInterface::MSG_ERROR);
+ "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE);
StartShutdown();
return;
}
diff --git a/src/serialize.h b/src/serialize.h
index 55b6891394..b9d5f95463 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -1116,14 +1116,21 @@ public:
}
}
+ /** Get wrapped FILE* with transfer of ownership.
+ * @note This will invalidate the CAutoFile object, and makes it the responsibility of the caller
+ * of this function to clean up the returned FILE*.
+ */
FILE* release() { FILE* ret = file; file = NULL; return ret; }
- operator FILE*() { return file; }
- FILE* operator->() { return file; }
- FILE& operator*() { return *file; }
- FILE** operator&() { return &file; }
- FILE* operator=(FILE* pnew) { return file = pnew; }
- bool operator!() { return (file == NULL); }
+ /** Get wrapped FILE* without transfer of ownership.
+ * @note Ownership of the FILE* will remain with this class. Use this only if the scope of the
+ * CAutoFile outlives use of the passed pointer.
+ */
+ FILE* Get() const { return file; }
+
+ /** Return true if the wrapped FILE* is NULL, false otherwise.
+ */
+ bool IsNull() const { return (file == NULL); }
//
// Stream subset
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 7bec12b665..f9746fdaa5 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -106,51 +106,6 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
BOOST_CHECK(!CNode::IsBanned(addr));
}
-static bool CheckNBits(unsigned int nbits1, int64_t time1, unsigned int nbits2, int64_t time2)\
-{
- if (time1 > time2)
- return CheckNBits(nbits2, time2, nbits1, time1);
- int64_t deltaTime = time2-time1;
-
- return CheckMinWork(nbits2, nbits1, deltaTime);
-}
-
-BOOST_AUTO_TEST_CASE(DoS_checknbits)
-{
- using namespace boost::assign; // for 'map_list_of()'
-
- // Timestamps,nBits from the bitcoin block chain.
- // These are the block-chain checkpoint blocks
- typedef std::map<int64_t, unsigned int> BlockData;
- BlockData chainData =
- map_list_of(1239852051,486604799)(1262749024,486594666)
- (1279305360,469854461)(1280200847,469830746)(1281678674,469809688)
- (1296207707,453179945)(1302624061,453036989)(1309640330,437004818)
- (1313172719,436789733);
-
- // Make sure CheckNBits considers every combination of block-chain-lock-in-points
- // "sane":
- BOOST_FOREACH(const BlockData::value_type& i, chainData)
- {
- BOOST_FOREACH(const BlockData::value_type& j, chainData)
- {
- BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first));
- }
- }
-
- // Test a couple of insane combinations:
- BlockData::value_type firstcheck = *(chainData.begin());
- BlockData::value_type lastcheck = *(chainData.rbegin());
-
- // First checkpoint difficulty at or a while after the last checkpoint time should fail when
- // compared to last checkpoint
- BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first));
- BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first));
-
- // ... but OK if enough time passed for difficulty to adjust downward:
- BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first));
-}
-
CTransaction RandomOrphan()
{
std::map<uint256, COrphanTx>::iterator it;
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 2cdafa4bdd..99b21a23a0 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -14,6 +14,7 @@
#include <vector>
#include <boost/test/unit_test.hpp>
+#include <boost/tuple/tuple.hpp>
using namespace std;
using namespace boost::tuples;
diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp
index 67d40a45c7..9151fdc0c8 100644
--- a/src/test/checkblock_tests.cpp
+++ b/src/test/checkblock_tests.cpp
@@ -36,7 +36,7 @@ bool read_block(const std::string& filename, CBlock& block)
fseek(fp, 8, SEEK_SET); // skip msgheader/size
CAutoFile filein(fp, SER_DISK, CLIENT_VERSION);
- if (!filein) return false;
+ if (filein.IsNull()) return false;
filein >> block;
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index afd63d2717..e50218d8ef 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -47,7 +47,7 @@ struct TestingSetup {
bool fFirstRun;
pwalletMain = new CWallet("wallet.dat");
pwalletMain->LoadWallet(fFirstRun);
- RegisterWallet(pwalletMain);
+ RegisterValidationInterface(pwalletMain);
#endif
nScriptCheckThreads = 3;
for (int i=0; i < nScriptCheckThreads-1; i++)
diff --git a/src/txmempool.h b/src/txmempool.h
index c63fd6f590..ad190eea9d 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -52,6 +52,19 @@ public:
class CMinerPolicyEstimator;
+/** An inpoint - a combination of a transaction and an index n into its vin */
+class CInPoint
+{
+public:
+ const CTransaction* ptx;
+ uint32_t n;
+
+ CInPoint() { SetNull(); }
+ CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; }
+ void SetNull() { ptx = NULL; n = (uint32_t) -1; }
+ bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); }
+};
+
/*
* CTxMemPool stores valid-according-to-the-current-best-chain
* transactions that may be included in the next block.
diff --git a/src/ui_interface.h b/src/ui_interface.h
index f5224ba57d..1231d5ed0b 100644
--- a/src/ui_interface.h
+++ b/src/ui_interface.h
@@ -63,6 +63,9 @@ public:
/** Force blocking, modal message box dialog (not just OS notification) */
MODAL = 0x10000000U,
+ /** Do not print contents of message to debug log */
+ SECURE = 0x40000000U,
+
/** Predefined combinations for certain default usage cases */
MSG_INFORMATION = ICON_INFORMATION,
MSG_WARNING = (ICON_WARNING | BTN_OK | MODAL),
diff --git a/src/util.cpp b/src/util.cpp
index 632d0965bf..544ffc98b8 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -395,7 +395,8 @@ boost::filesystem::path GetDefaultDataDir()
#endif
}
-static boost::filesystem::path pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1];
+static boost::filesystem::path pathCached;
+static boost::filesystem::path pathCachedNetSpecific;
static CCriticalSection csPathCached;
const boost::filesystem::path &GetDataDir(bool fNetSpecific)
@@ -404,10 +405,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
LOCK(csPathCached);
- int nNet = CBaseChainParams::MAX_NETWORK_TYPES;
- if (fNetSpecific) nNet = BaseParams().NetworkID();
-
- fs::path &path = pathCached[nNet];
+ fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached;
// This can be called during exceptions by LogPrintf(), so we cache the
// value so we don't have to do memory allocations after that.
@@ -433,8 +431,8 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
void ClearDatadirCache()
{
- std::fill(&pathCached[0], &pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1],
- boost::filesystem::path());
+ pathCached = boost::filesystem::path();
+ pathCachedNetSpecific = boost::filesystem::path();
}
boost::filesystem::path GetConfigFile()
diff --git a/src/version.h b/src/version.h
index 75cbec39b7..a1e440de24 100644
--- a/src/version.h
+++ b/src/version.h
@@ -33,8 +33,11 @@ static const int PROTOCOL_VERSION = 70002;
// initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;
+// In this version, 'getheaders' was introduced.
+static const int GETHEADERS_VERSION = 31800;
+
// disconnect from peers older than this proto version
-static const int MIN_PEER_PROTO_VERSION = 209;
+static const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION;
// nTime field added to CAddress, starting with this version;
// if possible, avoid requesting addresses nodes older than this
diff --git a/src/wallet.h b/src/wallet.h
index fa8a94dfc1..06706655f8 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -95,7 +95,7 @@ public:
/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
* and provides the ability to create new transactions.
*/
-class CWallet : public CCryptoKeyStore, public CWalletInterface
+class CWallet : public CCryptoKeyStore, public CValidationInterface
{
private:
bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const;