aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am16
-rw-r--r--src/bench/bench.cpp2
-rw-r--r--src/bench/bench.h23
-rw-r--r--src/bitcoin-cli.cpp2
-rw-r--r--src/bitcoin-tx.cpp2
-rw-r--r--src/bitcoind.cpp2
-rw-r--r--src/dbwrapper.h4
-rw-r--r--src/init.cpp62
-rw-r--r--src/leveldb/util/env_win.cc236
-rw-r--r--src/main.cpp10
-rw-r--r--src/main.h3
-rw-r--r--src/memusage.h2
-rw-r--r--src/miner.h2
-rw-r--r--src/net.cpp94
-rw-r--r--src/net.h27
-rw-r--r--src/policy/policy.h6
-rw-r--r--src/qt/addresstablemodel.cpp2
-rw-r--r--src/qt/bitcoinstrings.cpp42
-rw-r--r--src/qt/coincontroldialog.cpp2
-rw-r--r--src/qt/guiutil.cpp4
-rw-r--r--src/qt/guiutil.h4
-rw-r--r--src/qt/locale/bitcoin_en.ts179
-rw-r--r--src/qt/rpcconsole.cpp12
-rw-r--r--src/qt/rpcconsole.h1
-rw-r--r--src/qt/sendcoinsentry.cpp2
-rw-r--r--src/qt/signverifymessagedialog.cpp4
-rw-r--r--src/rpcblockchain.cpp11
-rw-r--r--src/rpcmining.cpp4
-rw-r--r--src/rpcnet.cpp13
-rw-r--r--src/rpcserver.cpp2
-rw-r--r--src/test/alert_tests.cpp4
-rw-r--r--src/test/data/tx_invalid.json10
-rw-r--r--src/test/test_bitcoin.cpp1
-rw-r--r--src/txdb.cpp2
-rw-r--r--src/txmempool.cpp21
-rw-r--r--src/txmempool.h5
-rw-r--r--src/util.cpp11
-rw-r--r--src/util.h3
-rw-r--r--src/utiltime.cpp8
-rw-r--r--src/utiltime.h1
-rw-r--r--src/wallet/db.cpp2
-rw-r--r--src/wallet/db.h2
-rw-r--r--src/wallet/test/wallet_tests.cpp113
-rw-r--r--src/wallet/wallet.cpp16
-rw-r--r--src/wallet/wallet.h29
-rw-r--r--src/wallet/walletdb.cpp7
-rw-r--r--src/zmq/zmqnotificationinterface.cpp11
-rw-r--r--src/zmq/zmqnotificationinterface.h3
48 files changed, 588 insertions, 436 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 312643cec3..f35b9dc898 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -412,7 +412,19 @@ libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BIT
endif
#
-CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno
+CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a
+CLEANFILES += *.gcda *.gcno
+CLEANFILES += compat/*.gcda compat/*.gcno
+CLEANFILES += consensus/*.gcda consensus/*.gcno
+CLEANFILES += crypto/*.gcda crypto/*.gcno
+CLEANFILES += policy/*.gcda policy/*.gcno
+CLEANFILES += primitives/*.gcda primitives/*.gcno
+CLEANFILES += script/*.gcda script/*.gcno
+CLEANFILES += support/*.gcda support/*.gcno
+CLEANFILES += univalue/*.gcda univalue/*.gcno
+CLEANFILES += wallet/*.gcda wallet/*.gcno
+CLEANFILES += wallet/test/*.gcda wallet/test/*.gcno
+CLEANFILES += zmq/*.gcda zmq/*.gcno
DISTCLEANFILES = obj/build.h
@@ -422,7 +434,7 @@ clean-local:
-$(MAKE) -C leveldb clean
-$(MAKE) -C secp256k1 clean
-$(MAKE) -C univalue clean
- rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno
+ -rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno
-rm -f config.h
.rc.o:
diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp
index 89c3b0cc2a..6ee3cdc27a 100644
--- a/src/bench/bench.cpp
+++ b/src/bench/bench.cpp
@@ -1,7 +1,9 @@
// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#include "bench.h"
+
#include <iostream>
#include <sys/time.h>
diff --git a/src/bench/bench.h b/src/bench/bench.h
index bf591a2be6..5ce13c642b 100644
--- a/src/bench/bench.h
+++ b/src/bench/bench.h
@@ -1,8 +1,16 @@
// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_BENCH_H
-#define BITCOIN_BENCH_H
+
+#ifndef BITCOIN_BENCH_BENCH_H
+#define BITCOIN_BENCH_BENCH_H
+
+#include <map>
+#include <string>
+
+#include <boost/function.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
// Simple micro-benchmarking framework; API mostly matches a subset of the Google Benchmark
// framework (see https://github.com/google/benchmark)
@@ -25,14 +33,7 @@ static void CODE_TO_TIME(benchmark::State& state)
BENCHMARK(CODE_TO_TIME);
*/
-
-
-#include <boost/function.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/stringize.hpp>
-#include <map>
-#include <string>
-
+
namespace benchmark {
class State {
@@ -68,4 +69,4 @@ namespace benchmark {
#define BENCHMARK(n) \
benchmark::BenchRunner BOOST_PP_CAT(bench_, BOOST_PP_CAT(__LINE__, n))(BOOST_PP_STRINGIZE(n), n);
-#endif // BITCOIN_BENCH_H
+#endif // BITCOIN_BENCH_BENCH_H
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 6f22c70494..9564573657 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -94,7 +94,7 @@ static bool AppInitRPC(int argc, char* argv[])
// Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
try {
SelectBaseParams(ChainNameFromCommandLine());
- } catch(std::exception &e) {
+ } catch (const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
return false;
}
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 3330fe5d12..48033cd8ad 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -37,7 +37,7 @@ static bool AppInitRawTx(int argc, char* argv[])
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
try {
SelectParams(ChainNameFromCommandLine());
- } catch(std::exception &e) {
+ } catch (const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
return false;
}
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index d2af897242..addf0e6a26 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -109,7 +109,7 @@ bool AppInit(int argc, char* argv[])
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
try {
SelectParams(ChainNameFromCommandLine());
- } catch(std::exception &e) {
+ } catch (const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
return false;
}
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index aa28767508..1d31ab8ae5 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -104,7 +104,7 @@ public:
try {
CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
ssKey >> key;
- } catch(std::exception &e) {
+ } catch (const std::exception&) {
return false;
}
return true;
@@ -120,7 +120,7 @@ public:
CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
ssValue.Xor(*obfuscate_key);
ssValue >> value;
- } catch(std::exception &e) {
+ } catch (const std::exception&) {
return false;
}
return true;
diff --git a/src/init.cpp b/src/init.cpp
index 5fd06b3444..cc055900f5 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -222,7 +222,6 @@ void Shutdown()
#if ENABLE_ZMQ
if (pzmqNotificationInterface) {
UnregisterValidationInterface(pzmqNotificationInterface);
- pzmqNotificationInterface->Shutdown();
delete pzmqNotificationInterface;
pzmqNotificationInterface = NULL;
}
@@ -307,8 +306,8 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS));
strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)"));
strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
- strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288));
- strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3));
+ strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS));
+ strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), DEFAULT_CHECKLEVEL));
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
if (mode == HMM_BITCOIND)
{
@@ -369,6 +368,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
" " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
+ strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), 0));
#ifdef ENABLE_WALLET
strUsage += HelpMessageGroup(_("Wallet options:"));
@@ -376,7 +376,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
if (showDebug)
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
- CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
+ CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
@@ -406,12 +406,16 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug)
{
strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", 1));
- strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", 100));
+#ifdef ENABLE_WALLET
+ strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
+#endif
strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", 0));
strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", 0));
strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages");
strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages");
+#ifdef ENABLE_WALLET
strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1));
+#endif
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0));
strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT));
strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT));
@@ -424,12 +428,13 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
- strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
+ strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_THREADS));
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
if (showDebug)
{
+ strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS));
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", 15));
strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 1));
strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> entries (default: %u)", 50000));
@@ -690,13 +695,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#endif
if (!SetupNetworking())
- return InitError("Error: Initializing networking failed");
+ return InitError("Initializing networking failed");
#ifndef WIN32
if (GetBoolArg("-sysperms", false)) {
#ifdef ENABLE_WALLET
if (!GetBoolArg("-disablewallet", false))
- return InitError("Error: -sysperms is not allowed in combination with enabled wallet functionality");
+ return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
#endif
} else {
umask(077);
@@ -727,6 +732,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Set this early so that parameter interactions go to console
fPrintToConsole = GetBoolArg("-printtoconsole", false);
fLogTimestamps = GetBoolArg("-logtimestamps", true);
+ fLogTimeMicros = GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);
fLogIPs = GetBoolArg("-logips", false);
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
@@ -826,19 +832,22 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Check for -debugnet
if (GetBoolArg("-debugnet", false))
- InitWarning(_("Warning: Unsupported argument -debugnet ignored, use -debug=net."));
+ InitWarning(_("Unsupported argument -debugnet ignored, use -debug=net."));
// Check for -socks - as this is a privacy risk to continue, exit here
if (mapArgs.count("-socks"))
- return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported."));
+ return InitError(_("Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported."));
// Check for -tor - as this is a privacy risk to continue, exit here
if (GetBoolArg("-tor", false))
- return InitError(_("Error: Unsupported argument -tor found, use -onion."));
+ return InitError(_("Unsupported argument -tor found, use -onion."));
if (GetBoolArg("-benchmark", false))
- InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench."));
+ InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench."));
// Checkmempool and checkblockindex default to true in regtest mode
- mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks()));
+ int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
+ if (ratio != 0) {
+ mempool.setSanityCheck(1.0 / ratio);
+ }
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
fCheckpointsEnabled = GetBoolArg("-checkpoints", true);
@@ -846,7 +855,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
int64_t nMempoolSizeLimit = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
int64_t nMempoolDescendantSizeLimit = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000;
if (nMempoolSizeLimit < 0 || nMempoolSizeLimit < nMempoolDescendantSizeLimit * 40)
- return InitError(strprintf(_("Error: -maxmempool must be at least %d MB"), GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) / 25));
+ return InitError(strprintf(_("-maxmempool must be at least %d MB"), GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) / 25));
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
@@ -915,7 +924,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"]));
if (nFeePerK > nHighTransactionFeeWarning)
- InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
+ InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
payTxFee = CFeeRate(nFeePerK, 1000);
if (payTxFee < ::minRelayTxFee)
{
@@ -929,7 +938,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maptxfee"]));
if (nMaxFee > nHighTransactionMaxFeeWarning)
- InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction."));
+ InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
maxTxFee = nMaxFee;
if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
{
@@ -1056,12 +1065,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
BOOST_FOREACH(string cmt, mapMultiArgs["-uacomment"])
{
if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
- return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt));
+ return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt));
uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT));
}
strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
- return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.",
+ return InitError(strprintf(_("Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments."),
strSubVersion.size(), MAX_SUBVERSION_LENGTH));
}
@@ -1170,10 +1179,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs);
if (pzmqNotificationInterface) {
- pzmqNotificationInterface->Initialize();
RegisterValidationInterface(pzmqNotificationInterface);
}
#endif
+ if (mapArgs.count("-maxuploadtarget")) {
+ CNode::SetMaxOutboundTarget(GetArg("-maxuploadtarget", 0)*1024*1024);
+ }
// ********************************************************* Step 7: load block chain
@@ -1280,9 +1291,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
uiInterface.InitMessage(_("Verifying blocks..."));
- if (fHavePruned && GetArg("-checkblocks", 288) > MIN_BLOCKS_TO_KEEP) {
+ if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) {
LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n",
- MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288));
+ MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", DEFAULT_CHECKBLOCKS));
}
{
@@ -1296,8 +1307,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
}
- if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3),
- GetArg("-checkblocks", 288))) {
+ if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", DEFAULT_CHECKLEVEL),
+ GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
strLoadError = _("Corrupted block database detected");
break;
}
@@ -1382,9 +1393,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
{
- string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
+ InitWarning(_("Error reading wallet.dat! All keys read correctly, but transaction data"
" or address book entries might be missing or incorrect."));
- InitWarning(msg);
}
else if (nLoadWalletRet == DB_TOO_NEW)
strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin Core") << "\n";
@@ -1565,7 +1575,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
scheduler.scheduleEvery(f, nPowTargetSpacing);
// Generate coins in the background
- GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
+ GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", DEFAULT_GENERATE_THREADS), Params());
// ********************************************************* Step 12: finished
diff --git a/src/leveldb/util/env_win.cc b/src/leveldb/util/env_win.cc
index ef2ecae830..e11a96b791 100644
--- a/src/leveldb/util/env_win.cc
+++ b/src/leveldb/util/env_win.cc
@@ -103,39 +103,20 @@ private:
DISALLOW_COPY_AND_ASSIGN(Win32RandomAccessFile);
};
-class Win32MapFile : public WritableFile
+class Win32WritableFile : public WritableFile
{
public:
- Win32MapFile(const std::string& fname);
+ Win32WritableFile(const std::string& fname);
+ ~Win32WritableFile();
- ~Win32MapFile();
virtual Status Append(const Slice& data);
virtual Status Close();
virtual Status Flush();
virtual Status Sync();
BOOL isEnable();
private:
- std::string _filename;
- HANDLE _hFile;
- size_t _page_size;
- size_t _map_size; // How much extra memory to map at a time
- char* _base; // The mapped region
- HANDLE _base_handle;
- char* _limit; // Limit of the mapped region
- char* _dst; // Where to write next (in range [base_,limit_])
- char* _last_sync; // Where have we synced up to
- uint64_t _file_offset; // Offset of base_ in file
- //LARGE_INTEGER file_offset_;
- // Have we done an munmap of unsynced data?
- bool _pending_sync;
-
- // Roundup x to a multiple of y
- static size_t _Roundup(size_t x, size_t y);
- size_t _TruncateToPageBoundary(size_t s);
- bool _UnmapCurrentRegion();
- bool _MapNewRegion();
- DISALLOW_COPY_AND_ASSIGN(Win32MapFile);
- BOOL _Init(LPCWSTR Path);
+ std::string filename_;
+ ::HANDLE _hFile;
};
class Win32FileLock : public FileLock
@@ -442,202 +423,63 @@ void Win32RandomAccessFile::_CleanUp()
}
}
-size_t Win32MapFile::_Roundup( size_t x, size_t y )
+Win32WritableFile::Win32WritableFile(const std::string& fname)
+ : filename_(fname)
{
- return ((x + y - 1) / y) * y;
+ std::wstring path;
+ ToWidePath(fname, path);
+ DWORD Flag = PathFileExistsW(path.c_str()) ? OPEN_EXISTING : CREATE_ALWAYS;
+ _hFile = CreateFileW(path.c_str(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
+ NULL,
+ Flag,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ // CreateFileW returns INVALID_HANDLE_VALUE in case of error, always check isEnable() before use
}
-size_t Win32MapFile::_TruncateToPageBoundary( size_t s )
+Win32WritableFile::~Win32WritableFile()
{
- s -= (s & (_page_size - 1));
- assert((s % _page_size) == 0);
- return s;
+ if (_hFile != INVALID_HANDLE_VALUE)
+ Close();
}
-bool Win32MapFile::_UnmapCurrentRegion()
+Status Win32WritableFile::Append(const Slice& data)
{
- bool result = true;
- if (_base != NULL) {
- if (_last_sync < _limit) {
- // Defer syncing this data until next Sync() call, if any
- _pending_sync = true;
- }
- if (!UnmapViewOfFile(_base) || !CloseHandle(_base_handle))
- result = false;
- _file_offset += _limit - _base;
- _base = NULL;
- _base_handle = NULL;
- _limit = NULL;
- _last_sync = NULL;
- _dst = NULL;
- // Increase the amount we map the next time, but capped at 1MB
- if (_map_size < (1<<20)) {
- _map_size *= 2;
- }
+ DWORD r = 0;
+ if (!WriteFile(_hFile, data.data(), data.size(), &r, NULL) || r != data.size()) {
+ return Status::IOError("Win32WritableFile.Append::WriteFile: "+filename_, Win32::GetLastErrSz());
}
- return result;
-}
-
-bool Win32MapFile::_MapNewRegion()
-{
- assert(_base == NULL);
- //LONG newSizeHigh = (LONG)((file_offset_ + map_size_) >> 32);
- //LONG newSizeLow = (LONG)((file_offset_ + map_size_) & 0xFFFFFFFF);
- DWORD off_hi = (DWORD)(_file_offset >> 32);
- DWORD off_lo = (DWORD)(_file_offset & 0xFFFFFFFF);
- LARGE_INTEGER newSize;
- newSize.QuadPart = _file_offset + _map_size;
- SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN);
- SetEndOfFile(_hFile);
-
- _base_handle = CreateFileMappingA(
- _hFile,
- NULL,
- PAGE_READWRITE,
- 0,
- 0,
- 0);
- if (_base_handle != NULL) {
- _base = (char*) MapViewOfFile(_base_handle,
- FILE_MAP_ALL_ACCESS,
- off_hi,
- off_lo,
- _map_size);
- if (_base != NULL) {
- _limit = _base + _map_size;
- _dst = _base;
- _last_sync = _base;
- return true;
- }
- }
- return false;
+ return Status::OK();
}
-Win32MapFile::Win32MapFile( const std::string& fname) :
- _filename(fname),
- _hFile(NULL),
- _page_size(Win32::g_PageSize),
- _map_size(_Roundup(65536, Win32::g_PageSize)),
- _base(NULL),
- _base_handle(NULL),
- _limit(NULL),
- _dst(NULL),
- _last_sync(NULL),
- _file_offset(0),
- _pending_sync(false)
+Status Win32WritableFile::Close()
{
- std::wstring path;
- ToWidePath(fname, path);
- _Init(path.c_str());
- assert((Win32::g_PageSize & (Win32::g_PageSize - 1)) == 0);
-}
-
-Status Win32MapFile::Append( const Slice& data )
-{
- const char* src = data.data();
- size_t left = data.size();
- Status s;
- while (left > 0) {
- assert(_base <= _dst);
- assert(_dst <= _limit);
- size_t avail = _limit - _dst;
- if (avail == 0) {
- if (!_UnmapCurrentRegion() ||
- !_MapNewRegion()) {
- return Status::IOError("WinMmapFile.Append::UnmapCurrentRegion or MapNewRegion: ", Win32::GetLastErrSz());
- }
- }
- size_t n = (left <= avail) ? left : avail;
- memcpy(_dst, src, n);
- _dst += n;
- src += n;
- left -= n;
- }
- return s;
-}
-
-Status Win32MapFile::Close()
-{
- Status s;
- size_t unused = _limit - _dst;
- if (!_UnmapCurrentRegion()) {
- s = Status::IOError("WinMmapFile.Close::UnmapCurrentRegion: ",Win32::GetLastErrSz());
- } else if (unused > 0) {
- // Trim the extra space at the end of the file
- LARGE_INTEGER newSize;
- newSize.QuadPart = _file_offset - unused;
- if (!SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN)) {
- s = Status::IOError("WinMmapFile.Close::SetFilePointer: ",Win32::GetLastErrSz());
- } else
- SetEndOfFile(_hFile);
- }
if (!CloseHandle(_hFile)) {
- if (s.ok()) {
- s = Status::IOError("WinMmapFile.Close::CloseHandle: ", Win32::GetLastErrSz());
- }
+ return Status::IOError("Win32WritableFile.Close::CloseHandle: "+filename_, Win32::GetLastErrSz());
}
_hFile = INVALID_HANDLE_VALUE;
- _base = NULL;
- _base_handle = NULL;
- _limit = NULL;
-
- return s;
-}
-
-Status Win32MapFile::Sync()
-{
- Status s;
- if (_pending_sync) {
- // Some unmapped data was not synced
- _pending_sync = false;
- if (!FlushFileBuffers(_hFile)) {
- s = Status::IOError("WinMmapFile.Sync::FlushFileBuffers: ",Win32::GetLastErrSz());
- }
- }
- if (_dst > _last_sync) {
- // Find the beginnings of the pages that contain the first and last
- // bytes to be synced.
- size_t p1 = _TruncateToPageBoundary(_last_sync - _base);
- size_t p2 = _TruncateToPageBoundary(_dst - _base - 1);
- _last_sync = _dst;
- if (!FlushViewOfFile(_base + p1, p2 - p1 + _page_size)) {
- s = Status::IOError("WinMmapFile.Sync::FlushViewOfFile: ",Win32::GetLastErrSz());
- }
- }
- return s;
+ return Status::OK();
}
-Status Win32MapFile::Flush()
+Status Win32WritableFile::Flush()
{
+ // Nothing to do here, there are no application-side buffers
return Status::OK();
}
-Win32MapFile::~Win32MapFile()
+Status Win32WritableFile::Sync()
{
- if (_hFile != INVALID_HANDLE_VALUE) {
- Win32MapFile::Close();
+ if (!FlushFileBuffers(_hFile)) {
+ return Status::IOError("Win32WritableFile.Sync::FlushFileBuffers "+filename_, Win32::GetLastErrSz());
}
+ return Status::OK();
}
-BOOL Win32MapFile::_Init( LPCWSTR Path )
-{
- DWORD Flag = PathFileExistsW(Path) ? OPEN_EXISTING : CREATE_ALWAYS;
- _hFile = CreateFileW(Path,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
- NULL,
- Flag,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if(!_hFile || _hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- else
- return TRUE;
-}
-
-BOOL Win32MapFile::isEnable()
+BOOL Win32WritableFile::isEnable()
{
- return _hFile ? TRUE : FALSE;
+ return _hFile != INVALID_HANDLE_VALUE;
}
Win32FileLock::Win32FileLock( const std::string& fname ) :
@@ -981,7 +823,7 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result )
{
Status sRet;
std::string path = fname;
- Win32MapFile* pMapFile = new Win32MapFile(ModifyPath(path));
+ Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path));
if(!pMapFile->isEnable()){
delete pMapFile;
*result = NULL;
@@ -995,7 +837,7 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul
{
Status sRet;
std::string path = fname;
- Win32MapFile* pFile = new Win32MapFile(ModifyPath(path));
+ Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path));
if(!pFile->isEnable()){
*result = NULL;
sRet = Status::IOError(fname,Win32::GetLastErrSz());
diff --git a/src/main.cpp b/src/main.cpp
index c340bcd5c4..5a0406c771 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3805,6 +3805,16 @@ void static ProcessGetData(CNode* pfrom)
}
}
}
+ // disconnect node in case we have reached the outbound limit for serving historical blocks
+ static const int nOneWeek = 7 * 24 * 60 * 60; // assume > 1 week = historical
+ if (send && CNode::OutboundTargetReached(true) && ( ((pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) )
+ {
+ LogPrint("net", "historical block serving limit reached, disconnect peer=%d\n", pfrom->GetId());
+
+ //disconnect node
+ pfrom->fDisconnect = true;
+ send = false;
+ }
// Pruned nodes may have deleted the block, so check whether
// it's available before trying to send.
if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
diff --git a/src/main.h b/src/main.h
index 202d2c772b..c3874be663 100644
--- a/src/main.h
+++ b/src/main.h
@@ -127,6 +127,9 @@ extern uint64_t nPruneTarget;
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */
static const unsigned int MIN_BLOCKS_TO_KEEP = 288;
+static const signed int DEFAULT_CHECKBLOCKS = MIN_BLOCKS_TO_KEEP;
+static const unsigned int DEFAULT_CHECKLEVEL = 3;
+
// Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat)
// At 1MB per block, 288 blocks = 288MB.
// Add 15% for Undo data = 331MB
diff --git a/src/memusage.h b/src/memusage.h
index b475c3313b..e96c5bf038 100644
--- a/src/memusage.h
+++ b/src/memusage.h
@@ -121,4 +121,4 @@ static inline size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& m)
}
-#endif
+#endif // BITCOIN_MEMUSAGE_H
diff --git a/src/miner.h b/src/miner.h
index 7e0e58d540..ad13204818 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -17,6 +17,8 @@ class CScript;
class CWallet;
namespace Consensus { struct Params; };
+static const int DEFAULT_GENERATE_THREADS = 1;
+
struct CBlockTemplate
{
CBlock block;
diff --git a/src/net.cpp b/src/net.cpp
index 58b946f4a1..e18e8d0e29 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -12,6 +12,7 @@
#include "addrman.h"
#include "chainparams.h"
#include "clientversion.h"
+#include "consensus/consensus.h"
#include "crypto/common.h"
#include "hash.h"
#include "primitives/transaction.h"
@@ -326,6 +327,11 @@ uint64_t CNode::nTotalBytesSent = 0;
CCriticalSection CNode::cs_totalBytesRecv;
CCriticalSection CNode::cs_totalBytesSent;
+uint64_t CNode::nMaxOutboundLimit = 0;
+uint64_t CNode::nMaxOutboundTotalBytesSentInCycle = 0;
+uint64_t CNode::nMaxOutboundTimeframe = 60*60*24; //1 day
+uint64_t CNode::nMaxOutboundCycleStartTime = 0;
+
CNode* FindNode(const CNetAddr& ip)
{
LOCK(cs_vNodes);
@@ -2083,6 +2089,94 @@ void CNode::RecordBytesSent(uint64_t bytes)
{
LOCK(cs_totalBytesSent);
nTotalBytesSent += bytes;
+
+ uint64_t now = GetTime();
+ if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
+ {
+ // timeframe expired, reset cycle
+ nMaxOutboundCycleStartTime = now;
+ nMaxOutboundTotalBytesSentInCycle = 0;
+ }
+
+ // TODO, exclude whitebind peers
+ nMaxOutboundTotalBytesSentInCycle += bytes;
+}
+
+void CNode::SetMaxOutboundTarget(uint64_t limit)
+{
+ LOCK(cs_totalBytesSent);
+ uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE;
+ nMaxOutboundLimit = limit;
+
+ if (limit < recommendedMinimum)
+ LogPrintf("Max outbound target is very small (%s) and will be overshot. Recommended minimum is %s\n.", nMaxOutboundLimit, recommendedMinimum);
+}
+
+uint64_t CNode::GetMaxOutboundTarget()
+{
+ LOCK(cs_totalBytesSent);
+ return nMaxOutboundLimit;
+}
+
+uint64_t CNode::GetMaxOutboundTimeframe()
+{
+ LOCK(cs_totalBytesSent);
+ return nMaxOutboundTimeframe;
+}
+
+uint64_t CNode::GetMaxOutboundTimeLeftInCycle()
+{
+ LOCK(cs_totalBytesSent);
+ if (nMaxOutboundLimit == 0)
+ return 0;
+
+ if (nMaxOutboundCycleStartTime == 0)
+ return nMaxOutboundTimeframe;
+
+ uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
+ uint64_t now = GetTime();
+ return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime();
+}
+
+void CNode::SetMaxOutboundTimeframe(uint64_t timeframe)
+{
+ LOCK(cs_totalBytesSent);
+ if (nMaxOutboundTimeframe != timeframe)
+ {
+ // reset measure-cycle in case of changing
+ // the timeframe
+ nMaxOutboundCycleStartTime = GetTime();
+ }
+ nMaxOutboundTimeframe = timeframe;
+}
+
+bool CNode::OutboundTargetReached(bool historicalBlockServingLimit)
+{
+ LOCK(cs_totalBytesSent);
+ if (nMaxOutboundLimit == 0)
+ return false;
+
+ if (historicalBlockServingLimit)
+ {
+ // keep a large enought buffer to at least relay each block once
+ uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
+ uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE;
+ if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
+ return true;
+ }
+ else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
+ return true;
+
+ return false;
+}
+
+uint64_t CNode::GetOutboundTargetBytesLeft()
+{
+ LOCK(cs_totalBytesSent);
+ if (nMaxOutboundLimit == 0)
+ return 0;
+
+ return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
}
uint64_t CNode::GetTotalBytesRecv()
diff --git a/src/net.h b/src/net.h
index 6842ee5edc..f90b3385af 100644
--- a/src/net.h
+++ b/src/net.h
@@ -400,6 +400,12 @@ private:
static uint64_t nTotalBytesRecv;
static uint64_t nTotalBytesSent;
+ // outbound limit & stats
+ static uint64_t nMaxOutboundTotalBytesSentInCycle;
+ static uint64_t nMaxOutboundCycleStartTime;
+ static uint64_t nMaxOutboundLimit;
+ static uint64_t nMaxOutboundTimeframe;
+
CNode(const CNode&);
void operator=(const CNode&);
@@ -701,6 +707,27 @@ public:
static uint64_t GetTotalBytesRecv();
static uint64_t GetTotalBytesSent();
+
+ //!set the max outbound target in bytes
+ static void SetMaxOutboundTarget(uint64_t limit);
+ static uint64_t GetMaxOutboundTarget();
+
+ //!set the timeframe for the max outbound target
+ static void SetMaxOutboundTimeframe(uint64_t timeframe);
+ static uint64_t GetMaxOutboundTimeframe();
+
+ //!check if the outbound target is reached
+ // if param historicalBlockServingLimit is set true, the function will
+ // response true if the limit for serving historical blocks has been reached
+ static bool OutboundTargetReached(bool historicalBlockServingLimit);
+
+ //!response the bytes left in the current max outbound cycle
+ // in case of no limit, it will always response 0
+ static uint64_t GetOutboundTargetBytesLeft();
+
+ //!response the time in second left in the current max outbound cycle
+ // in case of no limit, it will always response 0
+ static uint64_t GetMaxOutboundTimeLeftInCycle();
};
diff --git a/src/policy/policy.h b/src/policy/policy.h
index 0ea0d435ad..747c5ce8ce 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_POLICY_H
-#define BITCOIN_POLICY_H
+#ifndef BITCOIN_POLICY_POLICY_H
+#define BITCOIN_POLICY_POLICY_H
#include "consensus/consensus.h"
#include "script/interpreter.h"
@@ -56,4 +56,4 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason);
*/
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
-#endif // BITCOIN_POLICY_H
+#endif // BITCOIN_POLICY_POLICY_H
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index c5ac07cfc2..a488d298c4 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -218,7 +218,7 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const
QFont font;
if(index.column() == Address)
{
- font = GUIUtil::bitcoinAddressFont();
+ font = GUIUtil::fixedPitchFont();
}
return font;
}
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 3cde2657cf..538b8912ab 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -13,6 +13,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"(1 = keep tx meta data e.g. account owner and payment request information, 2 "
"= drop tx meta data)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"-maxtxfee is set very high! Fees this large could be paid on a single "
+"transaction."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"-paytxfee is set very high! This is the transaction fee you will pay if you "
+"send a transaction."),
+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 "
"a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"),
@@ -42,10 +48,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Distributed under the MIT software license, see the accompanying file "
"COPYING or <http://www.opensource.org/licenses/mit-license.php>."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Error: Listening for incoming connections failed (listen returned error %s)"),
+"Do not keep transactions in the mempool longer than <n> hours (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Error: Unsupported argument -socks found. Setting SOCKS version isn't "
-"possible anymore, only SOCKS5 proxies are supported."),
+"Error reading wallet.dat! All keys read correctly, but transaction data or "
+"address book entries might be missing or incorrect."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Error: Listening for incoming connections failed (listen returned error %s)"),
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)"),
@@ -127,9 +135,18 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software "
"written by Eric Young and UPnP software written by Thomas Bernard."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Total length of network version string (%i) exceeds maximum length (%i). "
+"Reduce the number or size of uacomments."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = "
+"no limit (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to %s on this computer. Bitcoin Core is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Unsupported argument -socks found. Setting SOCKS version isn't possible "
+"anymore, only SOCKS5 proxies are supported."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Use UPnP to map the listening port (default: 1 when listening and no -proxy)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
@@ -141,21 +158,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"WARNING: check your network connection, %d blocks received in the last %d "
"hours (%d expected)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Warning: -maxtxfee is set very high! Fees this large could be paid on a "
-"single transaction."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Warning: -paytxfee is set very high! This is the transaction fee you will "
-"pay if you send a transaction."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: The network does not appear to fully agree! Some miners appear to "
"be experiencing issues."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: We do not appear to fully agree with our peers! You may need to "
"upgrade, or other nodes may need to upgrade."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Warning: error reading wallet.dat! All keys read correctly, but transaction "
-"data or address book entries might be missing or incorrect."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"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."),
@@ -171,6 +179,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"),
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)"),
@@ -212,7 +221,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down.")
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."),
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 %s/kB) to add to transactions you send (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"),
@@ -233,6 +241,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Keep the transaction memory pool below <n> megabytes (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..."),
@@ -294,9 +303,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to start HTTP server. See debug log for details."),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -benchmark ignored, use -debug=bench."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -debugnet ignored, use -debug=net."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -tor found, use -onion."),
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
+QT_TRANSLATE_NOOP("bitcoin-core", "User Agent comment (%s) contains unsafe characters."),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet..."),
@@ -305,8 +317,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoi
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete; upgrade required!"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -benchmark ignored, use -debug=bench."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -debugnet ignored, use -debug=net."),
QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"),
QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "ZeroMQ notification options:"),
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 781d8f7e02..81b2597c3b 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -567,7 +567,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
nChange -= nPayFee;
// Never create dust outputs; if we would, just add the dust to the fee.
- if (nChange > 0 && nChange < CENT)
+ if (nChange > 0 && nChange < MIN_CHANGE)
{
CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0));
if (txout.IsDust(::minRelayTxFee))
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 8917f77f22..1c0056a7bd 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -88,7 +88,7 @@ QString dateTimeStr(qint64 nTime)
return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
}
-QFont bitcoinAddressFont()
+QFont fixedPitchFont()
{
QFont font("Monospace");
#if QT_VERSION >= 0x040800
@@ -103,7 +103,7 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
{
parent->setFocusProxy(widget);
- widget->setFont(bitcoinAddressFont());
+ widget->setFont(fixedPitchFont());
#if QT_VERSION >= 0x040700
// We don't want translators to use own addresses in translations
// and this is the only place, where this address is supplied.
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 0ac3db6327..ec678c4af2 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -37,8 +37,8 @@ namespace GUIUtil
QString dateTimeStr(const QDateTime &datetime);
QString dateTimeStr(qint64 nTime);
- // Render Bitcoin addresses in monospace font
- QFont bitcoinAddressFont();
+ // Return a monospace font
+ QFont fixedPitchFont();
// Set up widgets for address and amounts
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 3ebb4d0bf6..58921a9f8b 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -3706,7 +3706,7 @@
<context>
<name>bitcoin-core</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="+249"/>
+ <location filename="../bitcoinstrings.cpp" line="+258"/>
<source>Options:</source>
<translation>Options:</translation>
</message>
@@ -3731,7 +3731,7 @@
<translation>Accept command line and JSON-RPC commands</translation>
</message>
<message>
- <location line="-117"/>
+ <location line="-118"/>
<source>Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)</source>
<translation type="unfinished"></translation>
</message>
@@ -3771,17 +3771,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+109"/>
+ <location line="+110"/>
<source>Error: A fatal internal error occurred, see debug.log for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+3"/>
<source>Fee (in %s/kB) to add to transactions you send (default: %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+37"/>
+ <location line="+38"/>
<source>Pruning blockstore...</source>
<translation type="unfinished"></translation>
</message>
@@ -3796,17 +3796,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>Use the test network</source>
- <translation>Use the test network</translation>
- </message>
- <message>
- <location line="-123"/>
+ <location line="-119"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
<message>
- <location line="-157"/>
+ <location line="-160"/>
<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>
@@ -3821,7 +3816,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+13"/>
<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>
@@ -3841,12 +3836,12 @@
<translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+13"/>
<source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+6"/>
<source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source>
<translation type="unfinished"></translation>
</message>
@@ -3861,11 +3856,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <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>
- <message>
<location line="+3"/>
<source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
<translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation>
@@ -3877,11 +3867,6 @@
</message>
<message>
<location line="+3"/>
- <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
- <translation>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</translation>
- </message>
- <message>
- <location line="+3"/>
<source>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.</source>
<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>
@@ -3897,6 +3882,11 @@
</message>
<message>
<location line="+1"/>
+ <source>-maxmempool must be at least %d MB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>&lt;category&gt; can be:</source>
<translation type="unfinished"></translation>
</message>
@@ -3986,7 +3976,7 @@
<translation>Error: Disk space is low!</translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
<translation>Failed to listen on any port. Use -listen=0 if you want this.</translation>
</message>
@@ -4006,7 +3996,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+20"/>
+ <location line="+9"/>
+ <source>Keep the transaction memory pool below &lt;n&gt; megabytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+12"/>
<source>Not enough file descriptors available.</source>
<translation>Not enough file descriptors available.</translation>
</message>
@@ -4041,12 +4036,32 @@
<translation>Specify wallet file (within data directory)</translation>
</message>
<message>
- <location line="+17"/>
+ <location line="+16"/>
+ <source>Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Unsupported argument -tor found, use -onion.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+1"/>
+ <source>User Agent comment (%s) contains unsafe characters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>Verifying blocks...</source>
<translation>Verifying blocks...</translation>
</message>
@@ -4071,17 +4086,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+1"/>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>You need to rebuild the database using -reindex to change -txindex</translation>
</message>
<message>
- <location line="-89"/>
+ <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="-206"/>
+ <location line="-208"/>
<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>
@@ -4111,17 +4126,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+11"/>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+2"/>
- <source>Error: Unsupported argument -socks found. Setting SOCKS version isn&apos;t possible anymore, only SOCKS5 proxies are supported.</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>
@@ -4171,12 +4181,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+18"/>
- <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+22"/>
+ <location line="+40"/>
<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>
@@ -4191,7 +4196,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+6"/>
<source>Accept public REST requests (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4231,12 +4236,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>Error: Unsupported argument -tor found, use -onion.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+9"/>
+ <location line="+12"/>
<source>Information</source>
<translation>Information</translation>
</message>
@@ -4276,7 +4276,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+11"/>
<source>Need to specify a port with -whitebind: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -4391,7 +4391,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+9"/>
<source>Username for JSON-RPC connections</source>
<translation>Username for JSON-RPC connections</translation>
</message>
@@ -4406,17 +4406,7 @@
<translation>Warning</translation>
</message>
<message>
- <location line="+2"/>
- <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+3"/>
<source>Zapping all transactions from wallet...</source>
<translation type="unfinished"></translation>
</message>
@@ -4436,22 +4426,22 @@
<translation>wallet.dat corrupt, salvage failed</translation>
</message>
<message>
- <location line="-64"/>
+ <location line="-65"/>
<source>Password for JSON-RPC connections</source>
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-195"/>
+ <location line="-196"/>
<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="+242"/>
+ <location line="+246"/>
<source>Upgrade wallet to latest format</source>
<translation>Upgrade wallet to latest format</translation>
</message>
<message>
- <location line="-36"/>
+ <location line="-39"/>
<source>Rescan the block chain for missing wallet transactions</source>
<translation>Rescan the block chain for missing wallet transactions</translation>
</message>
@@ -4476,12 +4466,32 @@
<translation>Error loading wallet.dat: Wallet corrupted</translation>
</message>
<message>
- <location line="-196"/>
+ <location line="-205"/>
<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="+49"/>
+ <location line="+3"/>
+ <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Do not keep transactions in the mempool longer than &lt;n&gt; hours (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4501,17 +4511,32 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+51"/>
+ <location line="+46"/>
+ <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Unsupported argument -socks found. Setting SOCKS version isn&apos;t possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+37"/>
+ <location line="+28"/>
<source>(default: %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+11"/>
<source>Always query for peer addresses via DNS lookup (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4521,7 +4546,7 @@
<translation>Error loading wallet.dat</translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+10"/>
<source>Generate coins (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4541,7 +4566,7 @@
<translation>Invalid -proxy address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+9"/>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4641,7 +4666,7 @@
<translation>Cannot resolve -externalip address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+47"/>
+ <location line="+46"/>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
<translation>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
</message>
@@ -4651,7 +4676,7 @@
<translation>Insufficient funds</translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+14"/>
<source>Loading block index...</source>
<translation>Loading block index...</translation>
</message>
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index f387a3ec8c..8401701821 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -462,13 +462,19 @@ void RPCConsole::clear()
}
// Set default style sheet
+ QFontInfo fixedFontInfo(GUIUtil::fixedPitchFont());
+ // Try to make fixed font adequately large on different OS
+ QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 8.5 / 9);
ui->messagesWidget->document()->setDefaultStyleSheet(
+ QString(
"table { }"
"td.time { color: #808080; padding-top: 3px; } "
+ "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } "
"td.cmd-request { color: #006060; } "
"td.cmd-error { color: red; } "
"b { color: #006060; } "
- );
+ ).arg(fixedFontInfo.family(), ptSize)
+ );
message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "<br>" +
tr("Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") + "<br>" +
@@ -494,7 +500,7 @@ void RPCConsole::message(int category, const QString &message, bool html)
if(html)
out += message;
else
- out += GUIUtil::HtmlEscape(message, true);
+ out += GUIUtil::HtmlEscape(message, false);
out += "</td></tr></table>";
ui->messagesWidget->append(out);
}
@@ -849,4 +855,4 @@ void RPCConsole::showOrHideBanTableIfRequired()
bool visible = clientModel->getBanTableModel()->shouldShow();
ui->banlistWidget->setVisible(visible);
ui->banHeading->setVisible(visible);
-} \ No newline at end of file
+}
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index b86f776786..d5932ff149 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -71,6 +71,7 @@ private Q_SLOTS:
public Q_SLOTS:
void clear();
+ /** Append the message to the message widget */
void message(int category, const QString &message, bool html = false);
/** Set number of connections shown in the UI */
void setNumConnections(int count);
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 44aa8ad1af..4f4b5b70d5 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -40,7 +40,7 @@ SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *pare
// normal bitcoin address field
GUIUtil::setupAddressWidget(ui->payTo, this);
// just a label for displaying bitcoin address(es)
- ui->payTo_is->setFont(GUIUtil::bitcoinAddressFont());
+ ui->payTo_is->setFont(GUIUtil::fixedPitchFont());
// Connect signals
connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged()));
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 60e8e36ebe..96f50a2656 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -51,8 +51,8 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformSt
ui->messageIn_VM->installEventFilter(this);
ui->signatureIn_VM->installEventFilter(this);
- ui->signatureOut_SM->setFont(GUIUtil::bitcoinAddressFont());
- ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont());
+ ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont());
+ ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont());
}
SignVerifyMessageDialog::~SignVerifyMessageDialog()
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index 20c0c1fb2f..146eb3905a 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -539,13 +539,15 @@ UniValue gettxout(const UniValue& params, bool fHelp)
UniValue verifychain(const UniValue& params, bool fHelp)
{
+ int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL);
+ int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
if (fHelp || params.size() > 2)
throw runtime_error(
"verifychain ( checklevel numblocks )\n"
"\nVerifies blockchain database.\n"
"\nArguments:\n"
- "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
- "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
+ "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
+ "2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
"\nResult:\n"
"true|false (boolean) Verified or not\n"
"\nExamples:\n"
@@ -555,8 +557,6 @@ UniValue verifychain(const UniValue& params, bool fHelp)
LOCK(cs_main);
- int nCheckLevel = GetArg("-checklevel", 3);
- int nCheckDepth = GetArg("-checkblocks", 288);
if (params.size() > 0)
nCheckLevel = params[0].get_int();
if (params.size() > 1)
@@ -773,6 +773,9 @@ UniValue mempoolInfoToJSON()
ret.push_back(Pair("size", (int64_t) mempool.size()));
ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
+ size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
+ ret.push_back(Pair("maxmempool", (int64_t) maxmempool));
+ ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK())));
return ret;
}
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index c49c3e5194..f42b31627c 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -211,7 +211,7 @@ UniValue setgenerate(const UniValue& params, bool fHelp)
if (params.size() > 0)
fGenerate = params[0].get_bool();
- int nGenProcLimit = -1;
+ int nGenProcLimit = GetArg("-genproclimit", DEFAULT_GENERATE_THREADS);
if (params.size() > 1)
{
nGenProcLimit = params[1].get_int();
@@ -259,7 +259,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp)
obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
- obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
+ obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", DEFAULT_GENERATE_THREADS)));
obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index 7746be25f7..9bf017e385 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -29,7 +29,7 @@ UniValue getconnectioncount(const UniValue& params, bool fHelp)
throw runtime_error(
"getconnectioncount\n"
"\nReturns the number of connections to other nodes.\n"
- "\nbResult:\n"
+ "\nResult:\n"
"n (numeric) The connection count\n"
"\nExamples:\n"
+ HelpExampleCli("getconnectioncount", "")
@@ -83,7 +83,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
throw runtime_error(
"getpeerinfo\n"
"\nReturns data about each connected network node as a json array of objects.\n"
- "\nbResult:\n"
+ "\nResult:\n"
"[\n"
" {\n"
" \"id\": n, (numeric) Peer index\n"
@@ -379,6 +379,15 @@ UniValue getnettotals(const UniValue& params, bool fHelp)
obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
obj.push_back(Pair("timemillis", GetTimeMillis()));
+
+ UniValue outboundLimit(UniValue::VOBJ);
+ outboundLimit.push_back(Pair("timeframe", CNode::GetMaxOutboundTimeframe()));
+ outboundLimit.push_back(Pair("target", CNode::GetMaxOutboundTarget()));
+ outboundLimit.push_back(Pair("target_reached", CNode::OutboundTargetReached(false)));
+ outboundLimit.push_back(Pair("serve_historical_blocks", !CNode::OutboundTargetReached(true)));
+ outboundLimit.push_back(Pair("bytes_left_in_cycle", CNode::GetOutboundTargetBytesLeft()));
+ outboundLimit.push_back(Pair("time_left_in_cycle", CNode::GetMaxOutboundTimeLeftInCycle()));
+ obj.push_back(Pair("uploadtarget", outboundLimit));
return obj;
}
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index fa60f8c833..8bda5a0373 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -563,7 +563,7 @@ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int6
deadlineTimers.erase(name);
RPCTimerInterface* timerInterface = timerInterfaces[0];
LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
- deadlineTimers.insert(std::make_pair(name, timerInterface->NewTimer(func, nSeconds*1000)));
+ deadlineTimers.insert(std::make_pair(name, boost::shared_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000))));
}
const CRPCTable tableRPC;
diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp
index dd3c51d09b..468eda1c9b 100644
--- a/src/test/alert_tests.cpp
+++ b/src/test/alert_tests.cpp
@@ -217,10 +217,12 @@ BOOST_AUTO_TEST_CASE(PartitionAlert)
// use them
}
+ strMiscWarning = "";
+
// Test 1: chain with blocks every nPowTargetSpacing seconds,
// as normal, no worries:
PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
- BOOST_CHECK(strMiscWarning.empty());
+ BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning);
// Test 2: go 3.5 hours without a block, expect a warning:
now += 3*60*60+30*60;
diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json
index d3c8594342..cc059e814f 100644
--- a/src/test/data/tx_invalid.json
+++ b/src/test/data/tx_invalid.json
@@ -64,9 +64,13 @@
[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff655151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", "P2SH"],
-["Null txin"],
-[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "HASH160 0x14 0x02dae7dbbda56097959cba59b1989dd3e47937bf EQUAL"]],
-"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", "P2SH"],
+["Null txin, but without being a coinbase (because there are two inputs)"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"],
+ ["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
+"01000000020000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015100000000", "P2SH"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"],
+ ["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff010000000000000000015100000000", "P2SH"],
["Same as the transactions in valid with one input SIGHASH_ALL and one SIGHASH_ANYONECANPAY, but we set the _ANYONECANPAY sequence number, invalidating the SIGHASH_ALL signature"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"],
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index a74fbfc0d7..23e5e66d84 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -36,6 +36,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
{
ECC_Start();
SetupEnvironment();
+ SetupNetworking();
fPrintToDebugLog = false; // don't want to write to debug.log file
fCheckBlockIndex = true;
SelectParams(chainName);
diff --git a/src/txdb.cpp b/src/txdb.cpp
index f0868a1ebf..cd76c0155c 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -121,7 +121,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
nTotalAmount += out.nValue;
}
}
- stats.nSerializedSize += 32 + pcursor->GetKeySize();
+ stats.nSerializedSize += 32 + pcursor->GetValueSize();
ss << VARINT(0);
} else {
return error("CCoinsViewDB::GetStats() : unable to read value");
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index bb148005cd..a772e7adea 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -309,12 +309,12 @@ void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t
CTxMemPool::CTxMemPool(const CFeeRate& _minReasonableRelayFee) :
nTransactionsUpdated(0)
{
- clear();
+ _clear(); //lock free clear
// Sanity checks off by default for performance, because otherwise
// accepting transactions becomes O(N^2) where N is the number
// of transactions in the pool
- fSanityCheck = false;
+ nCheckFrequency = 0;
minerPolicyEstimator = new CBlockPolicyEstimator(_minReasonableRelayFee);
minReasonableRelayFee = _minReasonableRelayFee;
@@ -487,7 +487,7 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in
if (it2 != mapTx.end())
continue;
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
- if (fSanityCheck) assert(coins);
+ if (nCheckFrequency != 0) assert(coins);
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
transactionsToRemove.push_back(tx);
break;
@@ -512,6 +512,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>
if (txConflict != tx)
{
remove(txConflict, removed, true);
+ ClearPrioritisation(txConflict.GetHash());
}
}
}
@@ -546,9 +547,8 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
blockSinceLastRollingFeeBump = true;
}
-void CTxMemPool::clear()
+void CTxMemPool::_clear()
{
- LOCK(cs);
mapLinks.clear();
mapTx.clear();
mapNextTx.clear();
@@ -560,9 +560,18 @@ void CTxMemPool::clear()
++nTransactionsUpdated;
}
+void CTxMemPool::clear()
+{
+ LOCK(cs);
+ _clear();
+}
+
void CTxMemPool::check(const CCoinsViewCache *pcoins) const
{
- if (!fSanityCheck)
+ if (nCheckFrequency == 0)
+ return;
+
+ if (insecure_rand() >= nCheckFrequency)
return;
LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
diff --git a/src/txmempool.h b/src/txmempool.h
index d44995eefe..7b5843a8d0 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -278,7 +278,7 @@ public:
class CTxMemPool
{
private:
- bool fSanityCheck; //! Normally false, true if -checkmempool or -regtest
+ uint32_t nCheckFrequency; //! Value n means that n times in 2^32 we check.
unsigned int nTransactionsUpdated;
CBlockPolicyEstimator* minerPolicyEstimator;
@@ -360,7 +360,7 @@ public:
* check does nothing.
*/
void check(const CCoinsViewCache *pcoins) const;
- void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; }
+ void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = dFrequency * 4294967295.0; }
// addUnchecked must updated state for all ancestors of a given transaction,
// to track size/count of descendant transactions. First version of
@@ -375,6 +375,7 @@ public:
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);
void clear();
+ void _clear(); //lock free
void queryHashes(std::vector<uint256>& vtxid);
void pruneSpent(const uint256& hash, CCoins &coins);
unsigned int GetTransactionsUpdated() const;
diff --git a/src/util.cpp b/src/util.cpp
index 8192a7c71c..e8514a2ef0 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -108,6 +108,7 @@ bool fDaemon = false;
bool fServer = false;
string strMiscWarning;
bool fLogTimestamps = false;
+bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS;
bool fLogIPs = false;
volatile bool fReopenDebugLog = false;
CTranslationInterface translationInterface;
@@ -263,9 +264,13 @@ static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine
if (!fLogTimestamps)
return str;
- if (*fStartedNewLine)
- strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()) + ' ' + str;
- else
+ if (*fStartedNewLine) {
+ int64_t nTimeMicros = GetLogTimeMicros();
+ strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000);
+ if (fLogTimeMicros)
+ strStamped += strprintf(".%06d", nTimeMicros%1000000);
+ strStamped += ' ' + str;
+ } else
strStamped = str;
if (!str.empty() && str[str.size()-1] == '\n')
diff --git a/src/util.h b/src/util.h
index 0b2dc01ac6..b2779fe782 100644
--- a/src/util.h
+++ b/src/util.h
@@ -28,6 +28,8 @@
#include <boost/signals2/signal.hpp>
#include <boost/thread/exceptions.hpp>
+static const bool DEFAULT_LOGTIMEMICROS = false;
+
/** Signals for translation. */
class CTranslationInterface
{
@@ -44,6 +46,7 @@ extern bool fPrintToDebugLog;
extern bool fServer;
extern std::string strMiscWarning;
extern bool fLogTimestamps;
+extern bool fLogTimeMicros;
extern bool fLogIPs;
extern volatile bool fReopenDebugLog;
extern CTranslationInterface translationInterface;
diff --git a/src/utiltime.cpp b/src/utiltime.cpp
index d316288999..3202c47f1d 100644
--- a/src/utiltime.cpp
+++ b/src/utiltime.cpp
@@ -40,6 +40,14 @@ int64_t GetTimeMicros()
boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
}
+/** Return a time useful for the debug log */
+int64_t GetLogTimeMicros()
+{
+ if (nMockTime) return nMockTime*1000000;
+
+ return GetTimeMicros();
+}
+
void MilliSleep(int64_t n)
{
diff --git a/src/utiltime.h b/src/utiltime.h
index 900992f871..241b5211e9 100644
--- a/src/utiltime.h
+++ b/src/utiltime.h
@@ -12,6 +12,7 @@
int64_t GetTime();
int64_t GetTimeMillis();
int64_t GetTimeMicros();
+int64_t GetLogTimeMicros();
void SetMockTime(int64_t nMockTimeIn);
void MilliSleep(int64_t n);
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index e5bc653c33..cf6122813c 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -293,7 +293,7 @@ void CDB::Flush()
if (fReadOnly)
nMinutes = 1;
- bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0);
+ bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
}
void CDB::Close()
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 64071caa3a..46bc0ac0a9 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -20,6 +20,8 @@
#include <db_cxx.h>
+static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
+
extern unsigned int nWalletDBUpdated;
class CDBEnv
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index a5bc52b8dc..8b9292bd14 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
// try making 34 cents from 1,2,5,10,20 - we can't do it exactly
BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents
+ BOOST_CHECK_EQUAL(nValueRet, 35 * CENT); // but 35 cents is closest
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible)
// when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5
@@ -185,33 +185,34 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
- // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance
+ // empty the wallet and start again, now with fractions of a cent, to test small change avoidance
+
empty_wallet();
- add_coin(0.1*CENT);
- add_coin(0.2*CENT);
- add_coin(0.3*CENT);
- add_coin(0.4*CENT);
- add_coin(0.5*CENT);
-
- // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents
- // we'll get sub-cent change whatever happens, so can expect 1.0 exactly
- BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * CENT);
+ add_coin(0.1*MIN_CHANGE);
+ add_coin(0.2*MIN_CHANGE);
+ add_coin(0.3*MIN_CHANGE);
+ add_coin(0.4*MIN_CHANGE);
+ add_coin(0.5*MIN_CHANGE);
+
+ // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE
+ // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly
+ BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE);
- // but if we add a bigger coin, making it possible to avoid sub-cent change, things change:
- add_coin(1111*CENT);
+ // but if we add a bigger coin, small change is avoided
+ add_coin(1111*MIN_CHANGE);
- // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents
- BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount
+ // try making 1 from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5
+ BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount
- // if we add more sub-cent coins:
- add_coin(0.6*CENT);
- add_coin(0.7*CENT);
+ // if we add more small coins:
+ add_coin(0.6*MIN_CHANGE);
+ add_coin(0.7*MIN_CHANGE);
- // and try again to make 1.0 cents, we can still make 1.0 cents
- BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount
+ // and try again to make 1.0 * MIN_CHANGE
+ BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount
// run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf)
// they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change
@@ -223,45 +224,65 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount
BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins
- // if there's not enough in the smaller coins to make at least 1 cent change (0.5+0.6+0.7 < 1.0+1.0),
+ // if there's not enough in the smaller coins to make at least 1 * MIN_CHANGE change (0.5+0.6+0.7 < 1.0+1.0),
// we need to try finding an exact subset anyway
// sometimes it will fail, and so we use the next biggest coin:
empty_wallet();
- add_coin(0.5 * CENT);
- add_coin(0.6 * CENT);
- add_coin(0.7 * CENT);
- add_coin(1111 * CENT);
- BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin
+ add_coin(0.5 * MIN_CHANGE);
+ add_coin(0.6 * MIN_CHANGE);
+ add_coin(0.7 * MIN_CHANGE);
+ add_coin(1111 * MIN_CHANGE);
+ BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
// but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0)
empty_wallet();
- add_coin(0.4 * CENT);
- add_coin(0.6 * CENT);
- add_coin(0.8 * CENT);
- add_coin(1111 * CENT);
- BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount
+ add_coin(0.4 * MIN_CHANGE);
+ add_coin(0.6 * MIN_CHANGE);
+ add_coin(0.8 * MIN_CHANGE);
+ add_coin(1111 * MIN_CHANGE);
+ BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6
- // test avoiding sub-cent change
+ // test avoiding small change
empty_wallet();
- add_coin(0.0005 * COIN);
- add_coin(0.01 * COIN);
- add_coin(1 * COIN);
+ add_coin(0.05 * MIN_CHANGE);
+ add_coin(1 * MIN_CHANGE);
+ add_coin(100 * MIN_CHANGE);
- // trying to make 1.0001 from these three coins
- BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins
+ // trying to make 100.01 from these three coins
+ BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, 101.05 * MIN_CHANGE); // we should get all coins
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U);
- // but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change
- BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01
+ // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change
+ BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE);
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
+ // test with many inputs
+ for (CAmount amt=1500; amt < COIN; amt*=10) {
+ empty_wallet();
+ // Create 676 inputs (= MAX_STANDARD_TX_SIZE / 148 bytes per input)
+ for (uint16_t j = 0; j < 676; j++)
+ add_coin(amt);
+ BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, vCoins, setCoinsRet, nValueRet));
+ if (amt - 2000 < MIN_CHANGE) {
+ // needs more than one input:
+ uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt);
+ CAmount returnValue = amt * returnSize;
+ BOOST_CHECK_EQUAL(nValueRet, returnValue);
+ BOOST_CHECK_EQUAL(setCoinsRet.size(), returnSize);
+ } else {
+ // one input is sufficient:
+ BOOST_CHECK_EQUAL(nValueRet, amt);
+ BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+ }
+ }
+
// test randomness
{
empty_wallet();
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 8c0dad2381..cce3e40f38 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -47,7 +47,7 @@ bool fPayAtLeastCustomFee = true;
* Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
* Override with -mintxfee
*/
-CFeeRate CWallet::minTxFee = CFeeRate(1000);
+CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE);
/** @defgroup mapWallet
*
@@ -1497,9 +1497,6 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const
return nTotal;
}
-/**
- * populate vCoins with vector of available COutputs.
- */
void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue) const
{
vCoins.clear();
@@ -1619,7 +1616,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int
nValueRet += coin.first;
return true;
}
- else if (n < nTargetValue + CENT)
+ else if (n < nTargetValue + MIN_CHANGE)
{
vValue.push_back(coin);
nTotalLower += n;
@@ -1654,14 +1651,14 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int
vector<char> vfBest;
CAmount nBest;
- ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
- if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
- ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
+ ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest);
+ if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE)
+ ApproximateBestSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest);
// If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
// or the next bigger coin is closer), return the bigger coin
if (coinLowestLarger.second.first &&
- ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
+ ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLarger.first <= nBest))
{
setCoinsRet.insert(coinLowestLarger.second);
nValueRet += coinLowestLarger.first;
@@ -1844,6 +1841,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
LOCK2(cs_main, cs_wallet);
{
nFeeRet = 0;
+ // Start with no fee and loop until there is enough fee
while (true)
{
txNew.vin.clear();
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 22fe08670f..719f11f206 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -41,8 +41,12 @@ extern bool fPayAtLeastCustomFee;
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB
static const CAmount nHighTransactionFeeWarning = 0.01 * COIN;
+//! -mintxfee default
+static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
//! -maxtxfee default
static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN;
+//! minimum change amount
+static const CAmount MIN_CHANGE = CENT;
//! -txconfirmtarget default
static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2;
//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
@@ -442,6 +446,11 @@ public:
class CWallet : public CCryptoKeyStore, public CValidationInterface
{
private:
+ /**
+ * Select a set of coins such that nValueRet >= nTargetValue and at least
+ * all coins from coinControl are selected; Never select unconfirmed coins
+ * if they are not ours
+ */
bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const;
CWalletDB *pwalletdbEncryption;
@@ -539,7 +548,17 @@ public:
//! check whether we are allowed to upgrade (or already support) to the named feature
bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
+ /**
+ * populate vCoins with vector of available COutputs.
+ */
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, bool fIncludeZeroValue=false) const;
+
+ /**
+ * Shuffle and select coins until nTargetValue is reached while avoiding
+ * small change; This method is stochastic for some inputs and upon
+ * completion the coin set and corresponding actual target value is
+ * assembled
+ */
bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const;
bool IsSpent(const uint256& hash, unsigned int n) const;
@@ -622,7 +641,17 @@ public:
CAmount GetWatchOnlyBalance() const;
CAmount GetUnconfirmedWatchOnlyBalance() const;
CAmount GetImmatureWatchOnlyBalance() const;
+
+ /**
+ * Insert additional inputs into the transaction by
+ * calling CreateTransaction();
+ */
bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching);
+
+ /**
+ * Create a new transaction paying the recipients with a set of coins
+ * selected by SelectCoins(); Also create the change output, when needed
+ */
bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet,
std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 0624e442d1..ea8a4eb043 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -512,8 +512,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
}
else if (strType == "ckey")
{
- vector<unsigned char> vchPubKey;
+ CPubKey vchPubKey;
ssKey >> vchPubKey;
+ if (!vchPubKey.IsValid())
+ {
+ strErr = "Error reading wallet database: CPubKey corrupt";
+ return false;
+ }
vector<unsigned char> vchPrivKey;
ssValue >> vchPrivKey;
wss.nCKeys++;
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
index 388b86707b..09fe3aeb4c 100644
--- a/src/zmq/zmqnotificationinterface.cpp
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -21,8 +21,7 @@ CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL)
CZMQNotificationInterface::~CZMQNotificationInterface()
{
- // ensure Shutdown if Initialize is called
- assert(!pcontext);
+ Shutdown();
for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i)
{
@@ -59,6 +58,12 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const
{
notificationInterface = new CZMQNotificationInterface();
notificationInterface->notifiers = notifiers;
+
+ if (!notificationInterface->Initialize())
+ {
+ delete notificationInterface;
+ notificationInterface = NULL;
+ }
}
return notificationInterface;
@@ -99,7 +104,7 @@ bool CZMQNotificationInterface::Initialize()
return false;
}
- return false;
+ return true;
}
// Called during shutdown sequence
diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h
index 8eea15c068..3ccfaf341d 100644
--- a/src/zmq/zmqnotificationinterface.h
+++ b/src/zmq/zmqnotificationinterface.h
@@ -19,10 +19,11 @@ public:
static CZMQNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args);
+protected:
bool Initialize();
void Shutdown();
-protected: // CValidationInterface
+ // CValidationInterface
void SyncTransaction(const CTransaction &tx, const CBlock *pblock);
void UpdatedBlockTip(const CBlockIndex *pindex);