diff options
Diffstat (limited to 'src')
57 files changed, 1055 insertions, 357 deletions
diff --git a/src/.clang-format b/src/.clang-format index 5918819d13..2d2ee67035 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -23,7 +23,6 @@ ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: false DisableFormat: false -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, BOOST_REVERSE_FOREACH ] IndentCaseLabels: false IndentFunctionDeclarationAfterType: false IndentWidth: 4 diff --git a/src/Makefile.am b/src/Makefile.am index 9b9dd89f68..06b09404a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -124,9 +124,11 @@ BITCOIN_CORE_H = \ pow.h \ protocol.h \ random.h \ + reverse_iterator.h \ reverselock.h \ rpc/blockchain.h \ rpc/client.h \ + rpc/mining.h \ rpc/protocol.h \ rpc/server.h \ rpc/register.h \ diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 942942c299..f8956508f6 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -5,7 +5,6 @@ #include "bench.h" #include "wallet/wallet.h" -#include <boost/foreach.hpp> #include <set> static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<COutput>& vCoins) diff --git a/src/bloom.cpp b/src/bloom.cpp index cc3baa9185..fa884f0bf3 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -14,7 +14,6 @@ #include <math.h> #include <stdlib.h> -#include <boost/foreach.hpp> #define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455 #define LN2 0.6931471805599453094172321214581765680755001343602552 diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 13b5876530..e6b5fb72a7 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -6,12 +6,12 @@ #include "chain.h" #include "chainparams.h" +#include "reverse_iterator.h" #include "validation.h" #include "uint256.h" #include <stdint.h> -#include <boost/foreach.hpp> namespace Checkpoints { @@ -19,7 +19,7 @@ namespace Checkpoints { { const MapCheckpoints& checkpoints = data.mapCheckpoints; - BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints) + for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints)) { const uint256& hash = i.second; BlockMap::const_iterator t = mapBlockIndex.find(hash); diff --git a/src/checkqueue.h b/src/checkqueue.h index d7b7b836dc..408e278d21 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -10,7 +10,6 @@ #include <algorithm> #include <vector> -#include <boost/foreach.hpp> #include <boost/thread/condition_variable.hpp> #include <boost/thread/mutex.hpp> diff --git a/src/core_write.cpp b/src/core_write.cpp index 553ef44874..7f38e9e565 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -15,7 +15,6 @@ #include "utilmoneystr.h" #include "utilstrencodings.h" -#include <boost/foreach.hpp> std::string FormatScript(const CScript& script) { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 8c2e0da32f..a207d5ece4 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -18,7 +18,6 @@ #include <stdio.h> #include <boost/algorithm/string.hpp> // boost::trim -#include <boost/foreach.hpp> /** WWW-Authenticate to present with 401 Unauthorized response */ static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; diff --git a/src/init.cpp b/src/init.cpp index d59713258c..672ef77e80 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -447,7 +447,7 @@ std::string HelpMessage(HelpMessageMode mode) { strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); strUsage += HelpMessageOpt("-mocktime=<n>", "Replace actual time with <n> seconds since epoch (default: 0)"); - strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); + strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE)); } strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)"), @@ -1191,6 +1191,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD); InitSignatureCache(); + InitScriptExecutionCache(); LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads); if (nScriptCheckThreads) { @@ -1358,7 +1359,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("* Using %.1fMiB for in-memory UTXO set (plus up to %.1fMiB of unused mempool space)\n", nCoinCacheUsage * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024)); bool fLoaded = false; - while (!fLoaded) { + while (!fLoaded && !fRequestShutdown) { bool fReset = fReindex; std::string strLoadError; @@ -1389,6 +1390,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) break; } } + if (fRequestShutdown) break; if (!LoadBlockIndex(chainparams)) { strLoadError = _("Error loading block database"); @@ -1466,7 +1468,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fLoaded = true; } while(false); - if (!fLoaded) { + if (!fLoaded && !fRequestShutdown) { // first suggest a reindex if (!fReset) { bool fRet = uiInterface.ThreadSafeQuestion( diff --git a/src/memusage.h b/src/memusage.h index 710120d285..93fd6a0eb5 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -15,7 +15,6 @@ #include <unordered_map> #include <unordered_set> -#include <boost/foreach.hpp> namespace memusage { @@ -33,7 +33,6 @@ #include <arpa/inet.h> #endif -#include <boost/foreach.hpp> #include <boost/signals2/signal.hpp> class CScheduler; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 4d832f3711..a743f04dd1 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -22,6 +22,7 @@ #include "primitives/block.h" #include "primitives/transaction.h" #include "random.h" +#include "reverse_iterator.h" #include "tinyformat.h" #include "txmempool.h" #include "ui_interface.h" @@ -827,7 +828,7 @@ void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CB // Relay inventory, but don't relay old inventory during initial block download. connman->ForEachNode([nNewHeight, &vHashes](CNode* pnode) { if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 0)) { - BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { + for (const uint256& hash : reverse_iterate(vHashes)) { pnode->PushBlockHash(hash); } } @@ -2338,7 +2339,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } else { std::vector<CInv> vGetData; // Download as much as possible, from earliest to latest. - BOOST_REVERSE_FOREACH(const CBlockIndex *pindex, vToFetch) { + for (const CBlockIndex *pindex : reverse_iterate(vToFetch)) { if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { // Can't download any more from this peer break; diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 5f68c09a86..2f78d2f347 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -13,7 +13,6 @@ #include "util.h" #include "utilstrencodings.h" -#include <boost/foreach.hpp> CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn) { diff --git a/src/prevector.h b/src/prevector.h index dc17e7ce4b..02d860bb00 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -132,7 +132,7 @@ public: typedef const T* pointer; typedef const T& reference; typedef std::bidirectional_iterator_tag iterator_category; - const_reverse_iterator(T* ptr_) : ptr(ptr_) {} + const_reverse_iterator(const T* ptr_) : ptr(ptr_) {} const_reverse_iterator(reverse_iterator x) : ptr(&(*x)) {} const T& operator*() const { return *ptr; } const T* operator->() const { return ptr; } diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index d3ad24da01..2fa032abdc 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -10,7 +10,6 @@ #include "base58.h" #include "wallet/wallet.h" -#include <boost/foreach.hpp> #include <QFont> #include <QDebug> diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6d8760c071..8a745cadce 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -578,6 +578,7 @@ int main(int argc, char *argv[]) // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) // IMPORTANT if it is no longer a typedef use the normal variant above qRegisterMetaType< CAmount >("CAmount"); + qRegisterMetaType< std::function<void(void)> >("std::function<void(void)>"); /// 3. Application identification // must be set before OptionsModel is initialized or translations are loaded, diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index a1e5cccc0b..b3d2cf1d55 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -21,9 +21,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "A fee rate (in %s/kB) that will be used when fee estimation has insufficient " "data (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Accept connections from outside (default: 1 if no -proxy or -connect/-" -"noconnect)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Accept relayed transactions received from whitelisted peers even when not " "relaying transactions (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -37,14 +34,16 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Bind to given address and whitelist peers connecting to it. Use [host]:port " "notation for IPv6"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Bind to given address to listen for JSON-RPC connections. Use [host]:port " -"notation for IPv6. This option can be specified multiple times (default: " -"bind to all interfaces)"), +"Bind to given address to listen for JSON-RPC connections. This option is " +"ignored unless -rpcallowip is also passed. Port is optional and overrides -" +"rpcport. Use [host]:port notation for IPv6. This option can be specified " +"multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -" +"rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Cannot obtain a lock on data directory %s. %s is probably already running."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Connect only to the specified node(s); -noconnect or -connect=0 alone to " -"disable automatic connections"), +"Connect only to the specified node(s); -connect=0 disables automatic " +"connections"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Create new files with system default permissions, instead of umask 077 (only " "effective with disabled wallet functionality)"), @@ -62,13 +61,17 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Equivalent bytes per sigop in transactions for relay and mining (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Error loading %s: You can't enable HD on a already existing non-HD wallet"), +"Error loading %s: You can't enable HD on an already existing non-HD wallet"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Error reading %s! 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", "" +"Exclude debugging information for a category. Can be used in conjunction " +"with -debug=1 to output debug logs for all categories except one or more " +"specified categories."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when a relevant alert is received or we see a really long " "fork (%s in cmd is replaced by message)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -134,7 +137,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "reindex (download the whole blockchain again in case of pruned node)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Query for peer addresses via DNS lookup, if low on addresses (default: 1 " -"unless -connect/-noconnect)"), +"unless -connect used)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Randomize credentials for every proxy connection. This enables Tor stream " "isolation (default: %u)"), @@ -154,8 +157,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set lowest fee rate (in %s/kB) for transactions to be included in block " "creation. (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of script verification threads (%u to %d, 0 = auto, <0 = " "leave that many cores free, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -186,6 +187,9 @@ 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 replay blocks. You will need to rebuild the database using -" +"reindex-chainstate."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Unable to rewind the database to a pre-fork state. You will need to " "redownload the blockchain"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -225,6 +229,8 @@ 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", "" +"Whether to save the mempool on shutdown and load on restart (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR " "notated network (e.g. 1.2.3.0/24). Can be specified multiple times."), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -235,13 +241,17 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "mode. This will redownload the entire blockchain"), QT_TRANSLATE_NOOP("bitcoin-core", "" "You need to rebuild the database using -reindex-chainstate to change -txindex"), +QT_TRANSLATE_NOOP("bitcoin-core", "%d of last 100 blocks have unexpected version"), QT_TRANSLATE_NOOP("bitcoin-core", "%s corrupt, salvage failed"), QT_TRANSLATE_NOOP("bitcoin-core", "%s is set very high!"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "(press q to shutdown and continue later)"), QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"), +QT_TRANSLATE_NOOP("bitcoin-core", "-wallet parameter must only specify a filename (not a path)"), QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"), +QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"), QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"), @@ -274,10 +284,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environmen QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet corrupted"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet requires newer version of %s"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: You can't disable HD on a already existing HD wallet"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: You can't disable HD on an already existing HD wallet"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."), +QT_TRANSLATE_NOOP("bitcoin-core", "Error upgrading chainstate database"), 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!"), @@ -291,18 +302,19 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong da QT_TRANSLATE_NOOP("bitcoin-core", "Information"), QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. %s is shutting down."), QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"), -QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address: '%s'"), -QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address or hostname: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address or hostname: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -%s=<amount>: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -fallbackfee=<amount>: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid characters in -wallet filename"), 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", "Keypool ran out, please call keypoolrefill first"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading P2P addresses..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading banlist..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."), @@ -329,12 +341,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild chain state from the currently indexe QT_TRANSLATE_NOOP("bitcoin-core", "Reducing -maxconnections from %d to %d, because of system limitations."), QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Replaying blocks..."), QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), QT_TRANSLATE_NOOP("bitcoin-core", "Rewinding blocks..."), QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"), -QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions with full-RBF opt-in enabled (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"), @@ -374,13 +386,15 @@ 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", "Unsupported logging category %s=%s."), QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format on startup"), +QT_TRANSLATE_NOOP("bitcoin-core", "Upgrading UTXO database"), QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Use the test chain"), 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..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet(s)..."), QT_TRANSLATE_NOOP("bitcoin-core", "Wallet %s resides outside data directory %s"), QT_TRANSLATE_NOOP("bitcoin-core", "Wallet debugging/testing options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart %s to complete"), diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index f62f1e4a73..9183075067 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -127,7 +127,7 @@ <context> <name>AddressTableModel</name> <message> - <location filename="../addresstablemodel.cpp" line="+170"/> + <location filename="../addresstablemodel.cpp" line="+169"/> <source>Label</source> <translation type="unfinished"></translation> </message> @@ -304,12 +304,12 @@ <translation>Sign &message...</translation> </message> <message> - <location line="+427"/> + <location line="+429"/> <source>Synchronizing with network...</source> <translation>Synchronizing with network...</translation> </message> <message> - <location line="-505"/> + <location line="-507"/> <source>&Overview</source> <translation>&Overview</translation> </message> @@ -404,7 +404,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+357"/> + <location line="+359"/> <source>Click to disable network activity.</source> <translation type="unfinished"></translation> </message> @@ -429,7 +429,7 @@ <translation>Reindexing blocks on disk...</translation> </message> <message> - <location line="-508"/> + <location line="-510"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> @@ -459,12 +459,12 @@ <translation>&Verify message...</translation> </message> <message> - <location line="+514"/> + <location line="+516"/> <source>Bitcoin</source> <translation>Bitcoin</translation> </message> <message> - <location line="-739"/> + <location line="-741"/> <source>Wallet</source> <translation>Wallet</translation> </message> @@ -549,7 +549,7 @@ <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+354"/> + <location line="+356"/> <source>%n active connection(s) to Bitcoin network</source> <translation> <numerusform>%n active connection to Bitcoin network</numerusform> @@ -610,12 +610,12 @@ <translation>Up to date</translation> </message> <message> - <location line="-438"/> + <location line="-440"/> <source>Show the %1 help message to get a list with possible Bitcoin command-line options</source> <translation type="unfinished"></translation> </message> <message> - <location line="+197"/> + <location line="+199"/> <source>%1 client</source> <translation type="unfinished"></translation> </message> @@ -690,7 +690,7 @@ <translation>Wallet is <b>encrypted</b> and currently <b>locked</b></translation> </message> <message> - <location filename="../bitcoin.cpp" line="+518"/> + <location filename="../bitcoin.cpp" line="+524"/> <source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source> <translation type="unfinished"></translation> </message> @@ -783,7 +783,7 @@ <translation type="unfinished">Confirmed</translation> </message> <message> - <location filename="../coincontroldialog.cpp" line="+55"/> + <location filename="../coincontroldialog.cpp" line="+54"/> <source>Copy address</source> <translation type="unfinished"></translation> </message> @@ -849,7 +849,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+183"/> + <location line="+155"/> <source>yes</source> <translation type="unfinished"></translation> </message> @@ -956,7 +956,7 @@ <context> <name>FreespaceChecker</name> <message> - <location filename="../intro.cpp" line="+78"/> + <location filename="../intro.cpp" line="+76"/> <source>A new data directory will be created.</source> <translation>A new data directory will be created.</translation> </message> @@ -1068,12 +1068,22 @@ <translation type="unfinished"></translation> </message> <message> + <location line="+157"/> + <source>When you click OK, %1 will begin to download and process the full %4 block chain (%2GB) starting with the earliest transactions in %3 when %4 initially launched.</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+10"/> - <source>%1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source> + <source>This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off.</source> <translation type="unfinished"></translation> </message> <message> <location line="+10"/> + <source>If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-160"/> <source>Use the default data directory</source> <translation>Use the default data directory</translation> </message> @@ -1083,7 +1093,32 @@ <translation>Use a custom data directory:</translation> </message> <message> - <location filename="../intro.cpp" line="+94"/> + <location filename="../intro.cpp" line="+20"/> + <source>Bitcoin</source> + <translation type="unfinished">Bitcoin</translation> + </message> + <message> + <location line="+6"/> + <source>At least %1 GB of data will be stored in this directory, and it will grow over time.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Approximately %1 GB of data will be stored in this directory.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>%1 will download and store a copy of the Bitcoin block chain.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>The wallet will also be stored in this directory.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+70"/> <source>Error: Specified data directory "%1" cannot be created.</source> <translation type="unfinished"></translation> </message> @@ -1257,7 +1292,14 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+94"/> + <location line="-118"/> + <location line="+23"/> + <location line="+23"/> + <source>Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+166"/> <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> <translation type="unfinished"></translation> </message> @@ -1278,7 +1320,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+45"/> + <source>Open the %1 configuration file from the working directory.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Open Configuration File</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+10"/> <source>Reset all client options to default.</source> <translation>Reset all client options to default.</translation> </message> @@ -1288,7 +1340,7 @@ <translation>&Reset Options</translation> </message> <message> - <location line="-514"/> + <location line="-529"/> <source>&Network</source> <translation>&Network</translation> </message> @@ -1366,14 +1418,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> <location line="+23"/> - <location line="+23"/> - <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="-36"/> <source>IPv4</source> <translation type="unfinished"></translation> </message> @@ -1458,7 +1503,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+612"/> + <location line="+646"/> <source>&OK</source> <translation>&OK</translation> </message> @@ -1468,7 +1513,7 @@ <translation>&Cancel</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+86"/> + <location filename="../optionsdialog.cpp" line="+84"/> <source>default</source> <translation>default</translation> </message> @@ -1484,22 +1529,42 @@ </message> <message> <location line="+1"/> - <location line="+43"/> + <location line="+55"/> <source>Client restart required to activate changes.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-43"/> + <location line="-55"/> <source>Client will be shut down. Do you want to proceed?</source> <translation type="unfinished"></translation> </message> <message> - <location line="+47"/> + <location line="+15"/> + <source>Configuration options</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Error</source> + <translation type="unfinished">Error</translation> + </message> + <message> + <location line="+0"/> + <source>The configuration file could not be opened.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+38"/> <source>This change would require a client restart.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> + <location line="+28"/> <source>The supplied proxy address is invalid.</source> <translation>The supplied proxy address is invalid.</translation> </message> @@ -1755,12 +1820,12 @@ <translation type="unfinished">Amount</translation> </message> <message> - <location filename="../guiutil.cpp" line="+136"/> + <location filename="../guiutil.cpp" line="+130"/> <source>Enter a Bitcoin address (e.g. %1)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+759"/> + <location line="+766"/> <source>%1 d</source> <translation type="unfinished"></translation> </message> @@ -1850,7 +1915,7 @@ </translation> </message> <message> - <location filename="../bitcoin.cpp" line="+172"/> + <location filename="../bitcoin.cpp" line="+173"/> <source>%1 didn't yet exit safely...</source> <translation type="unfinished"></translation> </message> @@ -2007,7 +2072,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+404"/> + <location line="+324"/> + <source>&Reset</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+80"/> <location line="+558"/> <source>Received</source> <translation type="unfinished"></translation> @@ -2030,8 +2100,8 @@ </message> <message> <location line="+60"/> - <location filename="../rpcconsole.cpp" line="+456"/> - <location line="+719"/> + <location filename="../rpcconsole.cpp" line="+458"/> + <location line="+728"/> <source>Select a peer to view detailed information.</source> <translation type="unfinished"></translation> </message> @@ -2157,12 +2227,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+52"/> - <source>&Clear</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+16"/> + <location line="+68"/> <source>Totals</source> <translation type="unfinished"></translation> </message> @@ -2187,7 +2252,7 @@ <translation>Clear console</translation> </message> <message> - <location filename="../rpcconsole.cpp" line="-214"/> + <location filename="../rpcconsole.cpp" line="-223"/> <source>1 &hour</source> <translation type="unfinished"></translation> </message> @@ -2225,23 +2290,23 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+126"/> + <location line="+135"/> <source>Welcome to the %1 RPC console.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> - <translation>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</translation> - </message> - <message> - <location line="+1"/> + <location line="+2"/> <source>Type <b>help</b> for an overview of available commands.</source> <translation>Type <b>help</b> for an overview of available commands.</translation> </message> <message> - <location line="+2"/> - <source>WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramification of a command.</source> + <location line="-1"/> + <source>Use up and down arrows to navigate history, and %1 to clear screen.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.</source> <translation type="unfinished"></translation> </message> <message> @@ -2494,7 +2559,7 @@ <context> <name>RecentRequestsTableModel</name> <message> - <location filename="../recentrequeststablemodel.cpp" line="+29"/> + <location filename="../recentrequeststablemodel.cpp" line="+28"/> <source>Date</source> <translation type="unfinished">Date</translation> </message> @@ -2509,7 +2574,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+40"/> + <location line="+39"/> <source>(no label)</source> <translation type="unfinished"></translation> </message> @@ -2533,7 +2598,7 @@ <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+554"/> + <location filename="../sendcoinsdialog.cpp" line="+565"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -2608,7 +2673,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+37"/> + <location line="+24"/> + <source>Using the fallbackfee can result in sending a transaction that will take several hours or days (or never) to confirm. Consider choosing your fee manually or wait until your have validated the complete chain.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> + <source>Warning: Fee estimation is currently not possible.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+26"/> <source>collapse fee-settings</source> <translation type="unfinished"></translation> </message> @@ -2619,22 +2694,16 @@ </message> <message> <location line="-3"/> - <location line="+16"/> <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-64"/> + <location line="-48"/> <source>Hide</source> <translation type="unfinished"></translation> </message> <message> - <location line="+67"/> - <source>total at least</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+30"/> + <location line="+84"/> <location line="+13"/> <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source> <translation type="unfinished"></translation> @@ -2670,7 +2739,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+102"/> + <location line="+30"/> + <source>Request Replace-By-Fee</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Indicates that the sender may wish to replace this transaction with a new one paying higher fees (prior to being confirmed).</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+79"/> <source>Send to multiple recipients at once</source> <translation>Send to multiple recipients at once</translation> </message> @@ -2685,17 +2764,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-876"/> + <location line="-895"/> <source>Dust:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+691"/> + <location line="+700"/> <source>Confirmation time target:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+188"/> + <location line="+198"/> <source>Clear &All</source> <translation>Clear &All</translation> </message> @@ -2715,7 +2794,7 @@ <translation>S&end</translation> </message> <message> - <location filename="../sendcoinsdialog.cpp" line="-486"/> + <location filename="../sendcoinsdialog.cpp" line="-497"/> <source>Copy quantity</source> <translation type="unfinished"></translation> </message> @@ -2750,7 +2829,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+205"/> + <location line="+209"/> <location line="+5"/> <location line="+5"/> <location line="+4"/> @@ -2778,7 +2857,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> + <location line="+5"/> + <source>This transaction signals replaceability (optin-RBF).</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> <source>Confirm send coins</source> <translation type="unfinished"></translation> </message> @@ -2828,7 +2912,7 @@ <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+67"/> + <location line="+63"/> <source>%n block(s)</source> <translation> <numerusform>%n block</numerusform> @@ -2836,12 +2920,12 @@ </translation> </message> <message> - <location line="+28"/> + <location line="+24"/> <source>Pay only the required fee of %1</source> <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+25"/> + <location line="+30"/> <source>Estimated to begin confirmation within %n block(s).</source> <translation> <numerusform>Estimated to begin confirmation within %n block.</numerusform> @@ -2849,7 +2933,7 @@ </translation> </message> <message> - <location line="+102"/> + <location line="+103"/> <source>Warning: Invalid Bitcoin address</source> <translation type="unfinished"></translation> </message> @@ -2986,7 +3070,7 @@ <context> <name>SendConfirmationDialog</name> <message> - <location filename="../sendcoinsdialog.cpp" line="+95"/> + <location filename="../sendcoinsdialog.cpp" line="+86"/> <location line="+5"/> <source>Yes</source> <translation type="unfinished"></translation> @@ -3198,7 +3282,7 @@ <context> <name>TrafficGraphWidget</name> <message> - <location filename="../trafficgraphwidget.cpp" line="+79"/> + <location filename="../trafficgraphwidget.cpp" line="+80"/> <source>KB/s</source> <translation type="unfinished"></translation> </message> @@ -3427,7 +3511,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+20"/> <source>Amount</source> <translation type="unfinished">Amount</translation> </message> @@ -3460,7 +3544,7 @@ <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+246"/> + <location filename="../transactiontablemodel.cpp" line="+248"/> <source>Date</source> <translation type="unfinished">Date</translation> </message> @@ -3606,7 +3690,7 @@ <context> <name>TransactionView</name> <message> - <location filename="../transactionview.cpp" line="+69"/> + <location filename="../transactionview.cpp" line="+70"/> <location line="+16"/> <source>All</source> <translation type="unfinished"></translation> @@ -3677,12 +3761,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+36"/> + <location line="+37"/> <source>Abandon transaction</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> + <source>Increase transaction fee</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>Copy address</source> <translation type="unfinished"></translation> </message> @@ -3722,7 +3811,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+186"/> + <location line="+193"/> <source>Export Transaction History</source> <translation type="unfinished"></translation> </message> @@ -3787,7 +3876,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+147"/> + <location line="+166"/> <source>Range:</source> <translation type="unfinished"></translation> </message> @@ -3816,10 +3905,57 @@ <context> <name>WalletModel</name> <message> - <location filename="../walletmodel.cpp" line="+291"/> + <location filename="../walletmodel.cpp" line="+289"/> <source>Send Coins</source> <translation type="unfinished">Send Coins</translation> </message> + <message> + <location line="+385"/> + <location line="+46"/> + <location line="+9"/> + <source>Fee bump error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-55"/> + <source>Increasing transaction fee failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> + <source>Do you want to increase the fee?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> + <source>Current fee:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Increase:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>New fee:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Confirm fee bump</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+22"/> + <source>Can't sign transaction.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> + <source>Could not commit transaction</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>WalletView</name> @@ -3867,7 +4003,7 @@ <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+318"/> + <location filename="../bitcoinstrings.cpp" line="+330"/> <source>Options:</source> <translation>Options:</translation> </message> @@ -3877,37 +4013,27 @@ <translation>Specify data directory</translation> </message> <message> - <location line="-90"/> + <location line="-92"/> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connect to a node to retrieve peer addresses, and disconnect</translation> </message> <message> - <location line="+93"/> + <location line="+95"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> <message> - <location line="-108"/> + <location line="-111"/> <source>Accept command line and JSON-RPC commands</source> <translation>Accept command line and JSON-RPC commands</translation> </message> <message> - <location line="-221"/> - <source>Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+22"/> - <source>Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+12"/> + <location line="-197"/> <source>Distributed under the MIT software license, see the accompanying file %s or %s</source> <translation type="unfinished"></translation> </message> <message> - <location line="+37"/> + <location line="+41"/> <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> <translation type="unfinished"></translation> </message> @@ -3927,7 +4053,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+132"/> + <location line="+140"/> <source>Error: A fatal internal error occurred, see debug.log for details</source> <translation type="unfinished"></translation> </message> @@ -3937,22 +4063,22 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+40"/> + <location line="+41"/> <source>Pruning blockstore...</source> <translation type="unfinished"></translation> </message> <message> - <location line="+10"/> + <location line="+11"/> <source>Run in the background as a daemon and accept commands</source> <translation>Run in the background as a daemon and accept commands</translation> </message> <message> - <location line="+37"/> + <location line="+36"/> <source>Unable to start HTTP server. See debug log for details.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-360"/> + <location line="-372"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -3967,7 +4093,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> <source>Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)</source> <translation type="unfinished"></translation> </message> @@ -3977,7 +4103,7 @@ <translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation> </message> <message> - <location line="+10"/> + <location line="+12"/> <source>Cannot obtain a lock on data directory %s. %s is probably already running.</source> <translation type="unfinished"></translation> </message> @@ -3987,17 +4113,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>Error loading %s: You can't enable HD on a already existing non-HD wallet</source> + <location line="+15"/> + <source>Error reading %s! 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="+2"/> - <source>Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <location line="+5"/> + <source>Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+7"/> <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> @@ -4032,7 +4158,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+14"/> + <location line="+8"/> + <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect used)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> <source>Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB)</source> <translation type="unfinished"></translation> </message> @@ -4042,7 +4173,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> + <location line="+3"/> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation type="unfinished"></translation> </message> @@ -4058,6 +4189,11 @@ </message> <message> <location line="+15"/> + <source>Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain</source> <translation type="unfinished"></translation> </message> @@ -4087,27 +4223,52 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+3"/> + <source>Whether to save the mempool on shutdown and load on restart (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> <source>You need to rebuild the database using -reindex-chainstate to change -txindex</source> <translation type="unfinished"></translation> </message> <message> <location line="+2"/> + <source>%d of last 100 blocks have unexpected version</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>%s corrupt, salvage failed</source> <translation type="unfinished"></translation> </message> <message> <location line="+4"/> + <source>(press q to shutdown and continue later)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>-maxmempool must be at least %d MB</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> + <source>-wallet parameter must only specify a filename (not a path)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source><category> can be:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+2"/> + <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> <source>Append comment to the user agent string</source> <translation type="unfinished"></translation> </message> @@ -4217,12 +4378,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Error loading %s: You can't disable HD on a already existing HD wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+2"/> <source>Error loading block database</source> <translation>Error loading block database</translation> </message> @@ -4232,7 +4388,7 @@ <translation>Error opening block database</translation> </message> <message> - <location line="+4"/> + <location line="+5"/> <source>Error: Disk space is low!</source> <translation>Error: Disk space is low!</translation> </message> @@ -4257,27 +4413,32 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Invalid -onion address: '%s'</source> + <location line="+4"/> + <source>Invalid amount for -%s=<amount>: '%s'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Invalid amount for -fallbackfee=<amount>: '%s'</source> <translation type="unfinished"></translation> </message> <message> <location line="+2"/> - <source>Invalid amount for -%s=<amount>: '%s'</source> + <source>Invalid characters in -wallet filename</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Invalid amount for -fallbackfee=<amount>: '%s'</source> + <location line="+3"/> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> <translation type="unfinished"></translation> </message> <message> <location line="+4"/> - <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <source>Loading P2P addresses...</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> + <location line="+1"/> <source>Loading banlist...</source> <translation type="unfinished"></translation> </message> @@ -4327,12 +4488,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+4"/> + <source>Replaying blocks...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>Rewinding blocks...</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> + <location line="+4"/> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation type="unfinished"></translation> </message> @@ -4372,7 +4538,17 @@ <translation type="unfinished"></translation> </message> <message> + <location line="+1"/> + <source>Unsupported logging category %s=%s.</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+2"/> + <source>Upgrading UTXO database</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Use UPnP to map the listening port (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4392,12 +4568,7 @@ <translation>Verifying blocks...</translation> </message> <message> - <location line="+1"/> - <source>Verifying wallet...</source> - <translation>Verifying wallet...</translation> - </message> - <message> - <location line="+1"/> + <location line="+2"/> <source>Wallet %s resides outside data directory %s</source> <translation>Wallet %s resides outside data directory %s</translation> </message> @@ -4417,7 +4588,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-358"/> + <location line="-375"/> <source>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</source> <translation type="unfinished"></translation> </message> @@ -4427,12 +4598,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+9"/> + <location line="+14"/> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation type="unfinished"></translation> </message> @@ -4447,7 +4613,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> + <location line="+6"/> <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> @@ -4477,22 +4643,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+18"/> - <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+15"/> + <location line="+31"/> <source>The transaction amount is too small to send after the fee has been deducted</source> <translation type="unfinished"></translation> </message> <message> - <location line="+28"/> + <location line="+31"/> <source>Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start</source> <translation type="unfinished"></translation> </message> <message> - <location line="+31"/> + <location line="+33"/> <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> @@ -4502,12 +4663,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+9"/> <source>(default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+7"/> <source>Accept public REST requests (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4522,11 +4683,21 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+22"/> + <location line="+19"/> + <source>Error loading %s: You can't disable HD on an already existing HD wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>Error reading from database, shutting down.</source> <translation type="unfinished"></translation> </message> <message> + <location line="+1"/> + <source>Error upgrading chainstate database</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+8"/> <source>Imports blocks from external blk000??.dat file on startup</source> <translation type="unfinished"></translation> @@ -4537,12 +4708,22 @@ <translation>Information</translation> </message> <message> - <location line="+7"/> - <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <location line="+3"/> + <source>Invalid -onion address or hostname: '%s'</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> + <source>Invalid -proxy address or hostname: '%s'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>Invalid netmask specified in -whitelist: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4572,7 +4753,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+4"/> <source>Rescan the block chain for missing wallet transactions on startup</source> <translation type="unfinished"></translation> </message> @@ -4582,11 +4763,6 @@ <translation>Send trace/debug info to console instead of debug.log file</translation> </message> <message> - <location line="+1"/> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+7"/> <source>Show all debugging options (usage: --help -help-debug)</source> <translation type="unfinished"></translation> @@ -4642,17 +4818,22 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+8"/> <source>Upgrade wallet to latest format on startup</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+5"/> <source>Username for JSON-RPC connections</source> <translation>Username for JSON-RPC connections</translation> </message> <message> - <location line="+7"/> + <location line="+2"/> + <source>Verifying wallet(s)...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> <source>Warning</source> <translation>Warning</translation> </message> @@ -4677,27 +4858,22 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-73"/> + <location line="-75"/> <source>Password for JSON-RPC connections</source> <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-242"/> + <location line="-251"/> <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="+170"/> + <location line="+177"/> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> <message> - <location line="+58"/> - <source>Loading addresses...</source> - <translation>Loading addresses...</translation> - </message> - <message> - <location line="-291"/> + <location line="-243"/> <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> @@ -4707,7 +4883,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+19"/> + <source>Bind to given address to listen for JSON-RPC connections. This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>Connect only to the specified node(s); -connect=0 disables automatic connections</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+15"/> <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4717,7 +4903,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+2"/> + <source>Error loading %s: You can't enable HD on an already existing non-HD wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+26"/> <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> <translation type="unfinished"></translation> </message> @@ -4747,12 +4938,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+26"/> + <location line="+37"/> <source>Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)</source> <translation type="unfinished"></translation> </message> @@ -4782,7 +4968,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+9"/> <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> <translation type="unfinished"></translation> </message> @@ -4807,12 +4993,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+9"/> <source>Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple times.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+13"/> <source>%s is set very high!</source> <translation type="unfinished"></translation> </message> @@ -4822,12 +5008,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+11"/> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+38"/> + <location line="+39"/> <source>How many blocks to check at startup (default: %u, 0 = all)</source> <translation type="unfinished"></translation> </message> @@ -4837,12 +5023,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Invalid -proxy address: '%s'</source> - <translation>Invalid -proxy address: '%s'</translation> - </message> - <message> - <location line="+7"/> + <location line="+14"/> <source>Keypool ran out, please call keypoolrefill first</source> <translation type="unfinished"></translation> </message> @@ -4977,27 +5158,27 @@ <translation>Unknown network specified in -onlynet: '%s'</translation> </message> <message> - <location line="-80"/> + <location line="-81"/> <source>Insufficient funds</source> <translation>Insufficient funds</translation> </message> <message> - <location line="+14"/> + <location line="+15"/> <source>Loading block index...</source> <translation>Loading block index...</translation> </message> <message> - <location line="-61"/> + <location line="-63"/> <source>Add a node to connect to and attempt to keep the connection open</source> <translation>Add a node to connect to and attempt to keep the connection open</translation> </message> <message> - <location line="+62"/> + <location line="+64"/> <source>Loading wallet...</source> <translation>Loading wallet...</translation> </message> <message> - <location line="-55"/> + <location line="-57"/> <source>Cannot downgrade wallet</source> <translation>Cannot downgrade wallet</translation> </message> @@ -5007,17 +5188,17 @@ <translation>Cannot write default address</translation> </message> <message> - <location line="+78"/> + <location line="+81"/> <source>Rescanning...</source> <translation>Rescanning...</translation> </message> <message> - <location line="-67"/> + <location line="-70"/> <source>Done loading</source> <translation>Done loading</translation> </message> <message> - <location line="+15"/> + <location line="+16"/> <source>Error</source> <translation>Error</translation> </message> diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 470fb6b377..4e88c8802c 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -11,7 +11,6 @@ #include "clientversion.h" #include "streams.h" -#include <boost/foreach.hpp> RecentRequestsTableModel::RecentRequestsTableModel(CWallet *wallet, WalletModel *parent) : QAbstractTableModel(parent), walletModel(parent) diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 10966e42eb..1b7cc69231 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -131,6 +131,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) move(QApplication::desktop()->screenGeometry().center() - r.center()); subscribeToCoreSignals(); + installEventFilter(this); } SplashScreen::~SplashScreen() @@ -138,6 +139,16 @@ SplashScreen::~SplashScreen() unsubscribeFromCoreSignals(); } +bool SplashScreen::eventFilter(QObject * obj, QEvent * ev) { + if (ev->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev); + if(keyEvent->text()[0] == 'q' && breakAction != nullptr) { + breakAction(); + } + } + return QObject::eventFilter(obj, ev); +} + void SplashScreen::slotFinish(QWidget *mainWin) { Q_UNUSED(mainWin); @@ -164,6 +175,18 @@ static void ShowProgress(SplashScreen *splash, const std::string &title, int nPr InitMessage(splash, title + strprintf("%d", nProgress) + "%"); } +void SplashScreen::setBreakAction(const std::function<void(void)> &action) +{ + breakAction = action; +} + +static void SetProgressBreakAction(SplashScreen *splash, const std::function<void(void)> &action) +{ + QMetaObject::invokeMethod(splash, "setBreakAction", + Qt::QueuedConnection, + Q_ARG(std::function<void(void)>, action)); +} + #ifdef ENABLE_WALLET void SplashScreen::ConnectWallet(CWallet* wallet) { @@ -177,6 +200,7 @@ void SplashScreen::subscribeToCoreSignals() // Connect signals to client uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1)); uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); + uiInterface.SetProgressBreakAction.connect(boost::bind(SetProgressBreakAction, this, _1)); #ifdef ENABLE_WALLET uiInterface.LoadWallet.connect(boost::bind(&SplashScreen::ConnectWallet, this, _1)); #endif diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 95a65cc53c..a88ebb98a8 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_QT_SPLASHSCREEN_H #define BITCOIN_QT_SPLASHSCREEN_H +#include <functional> #include <QSplashScreen> class CWallet; @@ -35,6 +36,11 @@ public Q_SLOTS: /** Show message and progress */ void showMessage(const QString &message, int alignment, const QColor &color); + /** Sets the break action */ + void setBreakAction(const std::function<void(void)> &action); +protected: + bool eventFilter(QObject * obj, QEvent * ev); + private: /** Connect core signals to splash screen */ void subscribeToCoreSignals(); @@ -49,6 +55,8 @@ private: int curAlignment; QList<CWallet*> connectedWallets; + + std::function<void(void)> breakAction; }; #endif // BITCOIN_QT_SPLASHSCREEN_H diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index da070da084..03fd734e92 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -12,7 +12,6 @@ #include <stdint.h> -#include <boost/foreach.hpp> /* Return positive answer if transaction should be shown in list. */ diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index e3e070b27f..43d6e8826b 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -336,6 +336,10 @@ void TransactionView::changedAmount(const QString &amount) void TransactionView::exportClicked() { + if (!model || !model->getOptionsModel()) { + return; + } + // CSV is currently the only supported format QString filename = GUIUtil::getSaveFileName(this, tr("Export Transaction History"), QString(), diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 6538a80233..7eff783fe8 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -34,7 +34,6 @@ #include <QSet> #include <QTimer> -#include <boost/foreach.hpp> WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, OptionsModel *_optionsModel, QObject *parent) : QObject(parent), wallet(_wallet), optionsModel(_optionsModel), addressTableModel(0), diff --git a/src/reverse_iterator.h b/src/reverse_iterator.h new file mode 100644 index 0000000000..409f895ce0 --- /dev/null +++ b/src/reverse_iterator.h @@ -0,0 +1,39 @@ +// Taken from https://gist.github.com/arvidsson/7231973 + +#ifndef BITCOIN_REVERSE_ITERATOR_HPP +#define BITCOIN_REVERSE_ITERATOR_HPP + +/** + * Template used for reverse iteration in C++11 range-based for loops. + * + * std::vector<int> v = {1, 2, 3, 4, 5}; + * for (auto x : reverse_iterate(v)) + * std::cout << x << " "; + */ + +template <typename T> +class reverse_range +{ + T &x; + +public: + reverse_range(T &x) : x(x) {} + + auto begin() const -> decltype(this->x.rbegin()) + { + return x.rbegin(); + } + + auto end() const -> decltype(this->x.rend()) + { + return x.rend(); + } +}; + +template <typename T> +reverse_range<T> reverse_iterate(T &x) +{ + return reverse_range<T>(x); +} + +#endif // BITCOIN_REVERSE_ITERATOR_HPP diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 8c682592c5..e50742f36e 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -18,6 +18,7 @@ #include "policy/fees.h" #include "pow.h" #include "rpc/blockchain.h" +#include "rpc/mining.h" #include "rpc/server.h" #include "txmempool.h" #include "util.h" @@ -141,42 +142,6 @@ UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGen return blockHashes; } -UniValue generate(const JSONRPCRequest& request) -{ - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) - throw std::runtime_error( - "generate nblocks ( maxtries )\n" - "\nMine up to nblocks blocks immediately (before the RPC call returns)\n" - "\nArguments:\n" - "1. nblocks (numeric, required) How many blocks are generated immediately.\n" - "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" - "\nResult:\n" - "[ blockhashes ] (array) hashes of blocks generated\n" - "\nExamples:\n" - "\nGenerate 11 blocks\n" - + HelpExampleCli("generate", "11") - ); - - int nGenerate = request.params[0].get_int(); - uint64_t nMaxTries = 1000000; - if (request.params.size() > 1) { - nMaxTries = request.params[1].get_int(); - } - - std::shared_ptr<CReserveScript> coinbaseScript; - GetMainSignals().ScriptForMining(coinbaseScript); - - // If the keypool is exhausted, no script is returned at all. Catch this. - if (!coinbaseScript) - throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); - - //throw an error if no script was provided - if (coinbaseScript->reserveScript.empty()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)"); - - return generateBlocks(coinbaseScript, nGenerate, nMaxTries, true); -} - UniValue generatetoaddress(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) @@ -962,7 +927,6 @@ static const CRPCCommand commands[] = { "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} }, { "mining", "submitblock", &submitblock, true, {"hexdata","dummy"} }, - { "generating", "generate", &generate, true, {"nblocks","maxtries"} }, { "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} }, { "util", "estimatefee", &estimatefee, true, {"nblocks"} }, diff --git a/src/rpc/mining.h b/src/rpc/mining.h new file mode 100644 index 0000000000..a148d851da --- /dev/null +++ b/src/rpc/mining.h @@ -0,0 +1,15 @@ +// Copyright (c) 2017 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_RPC_MINING_H +#define BITCOIN_RPC_MINING_H + +#include "script/script.h" + +#include <univalue.h> + +/** Generate blocks (mine) */ +UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript); + +#endif diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 5cab0ad5bd..ed452fcb02 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -19,7 +19,6 @@ #include "utilstrencodings.h" #include "version.h" -#include <boost/foreach.hpp> #include <univalue.h> @@ -302,9 +301,8 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request) " ,...\n" "]\n" "\nExamples:\n" - + HelpExampleCli("getaddednodeinfo", "true") - + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"") - + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"") + + HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"") + + HelpExampleRpc("getaddednodeinfo", "\"192.168.0.201\"") ); if(!g_connman) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index c320d20453..63e4e9c630 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -17,7 +17,6 @@ #include <univalue.h> #include <boost/bind.hpp> -#include <boost/foreach.hpp> #include <boost/signals2/signal.hpp> #include <boost/algorithm/string/case_conv.hpp> // for to_upper() #include <boost/algorithm/string/classification.hpp> diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index 35b534344e..0a39619734 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -11,7 +11,6 @@ #include "script/standard.h" #include "script/sign.h" -#include <boost/foreach.hpp> typedef std::vector<unsigned char> valtype; diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index befc5f5233..ceb573b2ec 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -74,10 +74,10 @@ void InitSignatureCache() { // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, // setup_bytes creates the minimum possible cache (2 elements). - size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE)), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); + size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); size_t nElems = signatureCache.setup_bytes(nMaxCacheSize); - LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to store %zu elements\n", - (nElems*sizeof(uint256)) >>20, nMaxCacheSize>>20, nElems); + LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n", + (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); } bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const diff --git a/src/script/sign.cpp b/src/script/sign.cpp index ec93c5451b..dc50467d3f 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -12,7 +12,6 @@ #include "script/standard.h" #include "uint256.h" -#include <boost/foreach.hpp> typedef std::vector<unsigned char> valtype; diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 8e08acf0c6..760a5305e5 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -10,7 +10,6 @@ #include "util.h" #include "utilstrencodings.h" -#include <boost/foreach.hpp> typedef std::vector<unsigned char> valtype; diff --git a/src/sync.cpp b/src/sync.cpp index 94f2cafa98..c359e8220b 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -9,7 +9,6 @@ #include <stdio.h> -#include <boost/foreach.hpp> #include <boost/thread.hpp> #ifdef DEBUG_LOCKCONTENTION diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 01cc5ed831..c79675f5a6 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -9,7 +9,6 @@ #include <vector> #include <boost/algorithm/string.hpp> -#include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup) diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 6d8aab887b..c686f679c2 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -14,7 +14,6 @@ #include "test/test_bitcoin.h" -#include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> typedef std::vector<unsigned char> valtype; diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 11bb11d1e9..345c4a2148 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -5,6 +5,7 @@ #include <vector> #include "prevector.h" +#include "reverse_iterator.h" #include "serialize.h" #include "streams.h" @@ -56,13 +57,13 @@ class prevector_tester { for (const T& v : pre_vector) { local_check(v == real_vector[pos++]); } - BOOST_REVERSE_FOREACH(const T& v, pre_vector) { + for (const T& v : reverse_iterate(pre_vector)) { local_check(v == real_vector[--pos]); } for (const T& v : const_pre_vector) { local_check(v == real_vector[pos++]); } - BOOST_REVERSE_FOREACH(const T& v, const_pre_vector) { + for (const T& v : reverse_iterate(const_pre_vector)) { local_check(v == real_vector[--pos]); } CDataStream ss1(SER_DISK, 0); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 1bb191c73d..a18471588a 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -24,7 +24,6 @@ #include <string> #include <vector> -#include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> #include <univalue.h> diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index c60379982e..579e96524c 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -38,6 +38,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName) SetupEnvironment(); SetupNetworking(); InitSignatureCache(); + InitScriptExecutionCache(); fPrintToDebugLog = false; // don't want to write to debug.log file fCheckBlockIndex = true; SelectParams(chainName); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 778d2fd742..39f9f58604 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -27,7 +27,6 @@ #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> #include <univalue.h> diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index c5367208ba..a74f40251a 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -10,11 +10,17 @@ #include "txmempool.h" #include "random.h" #include "script/standard.h" +#include "script/sign.h" #include "test/test_bitcoin.h" #include "utiltime.h" +#include "core_io.h" +#include "keystore.h" +#include "policy/policy.h" #include <boost/test/unit_test.hpp> +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks); + BOOST_AUTO_TEST_SUITE(tx_validationcache_tests) static bool @@ -84,4 +90,282 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) BOOST_CHECK_EQUAL(mempool.size(), 0); } +// Run CheckInputs (using pcoinsTip) on the given transaction, for all script +// flags. Test that CheckInputs passes for all flags that don't overlap with +// the failing_flags argument, but otherwise fails. +// CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY (and future NOP codes that may +// get reassigned) have an interaction with DISCOURAGE_UPGRADABLE_NOPS: if +// the script flags used contain DISCOURAGE_UPGRADABLE_NOPS but don't contain +// CHECKLOCKTIMEVERIFY (or CHECKSEQUENCEVERIFY), but the script does contain +// OP_CHECKLOCKTIMEVERIFY (or OP_CHECKSEQUENCEVERIFY), then script execution +// should fail. +// Capture this interaction with the upgraded_nop argument: set it when evaluating +// any script flag that is implemented as an upgraded NOP code. +void ValidateCheckInputsForAllFlags(CMutableTransaction &tx, uint32_t failing_flags, bool add_to_cache, bool upgraded_nop) +{ + PrecomputedTransactionData txdata(tx); + // If we add many more flags, this loop can get too expensive, but we can + // rewrite in the future to randomly pick a set of flags to evaluate. + for (uint32_t test_flags=0; test_flags < (1U << 16); test_flags += 1) { + CValidationState state; + // Filter out incompatible flag choices + if ((test_flags & SCRIPT_VERIFY_CLEANSTACK)) { + // CLEANSTACK requires P2SH and WITNESS, see VerifyScript() in + // script/interpreter.cpp + test_flags |= SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS; + } + if ((test_flags & SCRIPT_VERIFY_WITNESS)) { + // WITNESS requires P2SH + test_flags |= SCRIPT_VERIFY_P2SH; + } + bool ret = CheckInputs(tx, state, pcoinsTip, true, test_flags, true, add_to_cache, txdata, nullptr); + // CheckInputs should succeed iff test_flags doesn't intersect with + // failing_flags + bool expected_return_value = !(test_flags & failing_flags); + if (expected_return_value && upgraded_nop) { + // If the script flag being tested corresponds to an upgraded NOP, + // then script execution should fail if DISCOURAGE_UPGRADABLE_NOPS + // is set. + expected_return_value = !(test_flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS); + } + BOOST_CHECK_EQUAL(ret, expected_return_value); + + // Test the caching + if (ret && add_to_cache) { + // Check that we get a cache hit if the tx was valid + std::vector<CScriptCheck> scriptchecks; + BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, test_flags, true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK(scriptchecks.empty()); + } else { + // Check that we get script executions to check, if the transaction + // was invalid, or we didn't add to cache. + std::vector<CScriptCheck> scriptchecks; + BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, test_flags, true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); + } + } +} + +BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) +{ + // Test that passing CheckInputs with one set of script flags doesn't imply + // that we would pass again with a different set of flags. + InitScriptExecutionCache(); + + CScript p2pk_scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + CScript p2sh_scriptPubKey = GetScriptForDestination(CScriptID(p2pk_scriptPubKey)); + CScript p2pkh_scriptPubKey = GetScriptForDestination(coinbaseKey.GetPubKey().GetID()); + CScript p2wpkh_scriptPubKey = GetScriptForWitness(p2pkh_scriptPubKey); + + CBasicKeyStore keystore; + keystore.AddKey(coinbaseKey); + keystore.AddCScript(p2pk_scriptPubKey); + + // flags to test: SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, SCRIPT_VERIFY_CHECKSEQUENCE_VERIFY, SCRIPT_VERIFY_NULLDUMMY, uncompressed pubkey thing + + // Create 2 outputs that match the three scripts above, spending the first + // coinbase tx. + CMutableTransaction spend_tx; + + spend_tx.nVersion = 1; + spend_tx.vin.resize(1); + spend_tx.vin[0].prevout.hash = coinbaseTxns[0].GetHash(); + spend_tx.vin[0].prevout.n = 0; + spend_tx.vout.resize(4); + spend_tx.vout[0].nValue = 11*CENT; + spend_tx.vout[0].scriptPubKey = p2sh_scriptPubKey; + spend_tx.vout[1].nValue = 11*CENT; + spend_tx.vout[1].scriptPubKey = p2wpkh_scriptPubKey; + spend_tx.vout[2].nValue = 11*CENT; + spend_tx.vout[2].scriptPubKey = CScript() << OP_CHECKLOCKTIMEVERIFY << OP_DROP << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + spend_tx.vout[3].nValue = 11*CENT; + spend_tx.vout[3].scriptPubKey = CScript() << OP_CHECKSEQUENCEVERIFY << OP_DROP << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + + // Sign, with a non-DER signature + { + std::vector<unsigned char> vchSig; + uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); + BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); + vchSig.push_back((unsigned char) 0); // padding byte makes this non-DER + vchSig.push_back((unsigned char)SIGHASH_ALL); + spend_tx.vin[0].scriptSig << vchSig; + } + + LOCK(cs_main); + + // Test that invalidity under a set of flags doesn't preclude validity + // under other (eg consensus) flags. + // spend_tx is invalid according to DERSIG + CValidationState state; + { + PrecomputedTransactionData ptd_spend_tx(spend_tx); + + BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); + + // If we call again asking for scriptchecks (as happens in + // ConnectBlock), we should add a script check object for this -- we're + // not caching invalidity (if that changes, delete this test case). + std::vector<CScriptCheck> scriptchecks; + BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); + BOOST_CHECK_EQUAL(scriptchecks.size(), 1); + + // Test that CheckInputs returns true iff DERSIG-enforcing flags are + // not present. Don't add these checks to the cache, so that we can + // test later that block validation works fine in the absence of cached + // successes. + ValidateCheckInputsForAllFlags(spend_tx, SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false, false); + + // And if we produce a block with this tx, it should be valid (DERSIG not + // enabled yet), even though there's no cache entry. + CBlock block; + + block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); + BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash()); + BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash()); + } + + // Test P2SH: construct a transaction that is valid without P2SH, and + // then test validity with P2SH. + { + CMutableTransaction invalid_under_p2sh_tx; + invalid_under_p2sh_tx.nVersion = 1; + invalid_under_p2sh_tx.vin.resize(1); + invalid_under_p2sh_tx.vin[0].prevout.hash = spend_tx.GetHash(); + invalid_under_p2sh_tx.vin[0].prevout.n = 0; + invalid_under_p2sh_tx.vout.resize(1); + invalid_under_p2sh_tx.vout[0].nValue = 11*CENT; + invalid_under_p2sh_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; + std::vector<unsigned char> vchSig2(p2pk_scriptPubKey.begin(), p2pk_scriptPubKey.end()); + invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2; + + ValidateCheckInputsForAllFlags(invalid_under_p2sh_tx, SCRIPT_VERIFY_P2SH, true, false); + } + + // Test CHECKLOCKTIMEVERIFY + { + CMutableTransaction invalid_with_cltv_tx; + invalid_with_cltv_tx.nVersion = 1; + invalid_with_cltv_tx.nLockTime = 100; + invalid_with_cltv_tx.vin.resize(1); + invalid_with_cltv_tx.vin[0].prevout.hash = spend_tx.GetHash(); + invalid_with_cltv_tx.vin[0].prevout.n = 2; + invalid_with_cltv_tx.vin[0].nSequence = 0; + invalid_with_cltv_tx.vout.resize(1); + invalid_with_cltv_tx.vout[0].nValue = 11*CENT; + invalid_with_cltv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; + + // Sign + std::vector<unsigned char> vchSig; + uint256 hash = SignatureHash(spend_tx.vout[2].scriptPubKey, invalid_with_cltv_tx, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); + BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101; + + ValidateCheckInputsForAllFlags(invalid_with_cltv_tx, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true); + + // Make it valid, and check again + invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; + CValidationState state; + PrecomputedTransactionData txdata(invalid_with_cltv_tx); + BOOST_CHECK(CheckInputs(invalid_with_cltv_tx, state, pcoinsTip, true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); + } + + // TEST CHECKSEQUENCEVERIFY + { + CMutableTransaction invalid_with_csv_tx; + invalid_with_csv_tx.nVersion = 2; + invalid_with_csv_tx.vin.resize(1); + invalid_with_csv_tx.vin[0].prevout.hash = spend_tx.GetHash(); + invalid_with_csv_tx.vin[0].prevout.n = 3; + invalid_with_csv_tx.vin[0].nSequence = 100; + invalid_with_csv_tx.vout.resize(1); + invalid_with_csv_tx.vout[0].nValue = 11*CENT; + invalid_with_csv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; + + // Sign + std::vector<unsigned char> vchSig; + uint256 hash = SignatureHash(spend_tx.vout[3].scriptPubKey, invalid_with_csv_tx, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); + BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101; + + ValidateCheckInputsForAllFlags(invalid_with_csv_tx, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true); + + // Make it valid, and check again + invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; + CValidationState state; + PrecomputedTransactionData txdata(invalid_with_csv_tx); + BOOST_CHECK(CheckInputs(invalid_with_csv_tx, state, pcoinsTip, true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); + } + + // TODO: add tests for remaining script flags + + // Test that passing CheckInputs with a valid witness doesn't imply success + // for the same tx with a different witness. + { + CMutableTransaction valid_with_witness_tx; + valid_with_witness_tx.nVersion = 1; + valid_with_witness_tx.vin.resize(1); + valid_with_witness_tx.vin[0].prevout.hash = spend_tx.GetHash(); + valid_with_witness_tx.vin[0].prevout.n = 1; + valid_with_witness_tx.vout.resize(1); + valid_with_witness_tx.vout[0].nValue = 11*CENT; + valid_with_witness_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; + + // Sign + SignatureData sigdata; + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata); + UpdateTransaction(valid_with_witness_tx, 0, sigdata); + + // This should be valid under all script flags. + ValidateCheckInputsForAllFlags(valid_with_witness_tx, 0, true, false); + + // Remove the witness, and check that it is now invalid. + valid_with_witness_tx.vin[0].scriptWitness.SetNull(); + ValidateCheckInputsForAllFlags(valid_with_witness_tx, SCRIPT_VERIFY_WITNESS, true, false); + } + + { + // Test a transaction with multiple inputs. + CMutableTransaction tx; + + tx.nVersion = 1; + tx.vin.resize(2); + tx.vin[0].prevout.hash = spend_tx.GetHash(); + tx.vin[0].prevout.n = 0; + tx.vin[1].prevout.hash = spend_tx.GetHash(); + tx.vin[1].prevout.n = 1; + tx.vout.resize(1); + tx.vout[0].nValue = 22*CENT; + tx.vout[0].scriptPubKey = p2pk_scriptPubKey; + + // Sign + for (int i=0; i<2; ++i) { + SignatureData sigdata; + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata); + UpdateTransaction(tx, i, sigdata); + } + + // This should be valid under all script flags + ValidateCheckInputsForAllFlags(tx, 0, true, false); + + // Check that if the second input is invalid, but the first input is + // valid, the transaction is not cached. + // Invalidate vin[1] + tx.vin[1].scriptWitness.SetNull(); + + CValidationState state; + PrecomputedTransactionData txdata(tx); + // This transaction is now invalid under segwit, because of the second input. + BOOST_CHECK(!CheckInputs(tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); + + std::vector<CScriptCheck> scriptchecks; + // Make sure this transaction was not cached (ie because the first + // input was valid) + BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); + // Should get 2 script checks back -- caching is on a whole-transaction basis. + BOOST_CHECK_EQUAL(scriptchecks.size(), 2); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/timedata.cpp b/src/timedata.cpp index d736baa213..099ed7f042 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -15,7 +15,6 @@ #include "utilstrencodings.h" #include "warnings.h" -#include <boost/foreach.hpp> static CCriticalSection cs_nTimeOffset; static int64_t nTimeOffset = 0; diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 4cd64bf028..3665e7e770 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -17,7 +17,6 @@ #include <boost/bind.hpp> #include <boost/signals2/signal.hpp> -#include <boost/foreach.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/replace.hpp> diff --git a/src/txdb.cpp b/src/txdb.cpp index d24162ba2d..002f6550bc 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -11,6 +11,8 @@ #include "pow.h" #include "uint256.h" #include "util.h" +#include "ui_interface.h" +#include "init.h" #include <stdint.h> @@ -366,13 +368,30 @@ bool CCoinsViewDB::Upgrade() { return true; } - LogPrintf("Upgrading database...\n"); + int64_t count = 0; + LogPrintf("Upgrading utxo-set database...\n"); + LogPrintf("[0%%]..."); size_t batch_size = 1 << 24; CDBBatch batch(db); + uiInterface.SetProgressBreakAction(StartShutdown); + int reportDone = 0; while (pcursor->Valid()) { boost::this_thread::interruption_point(); + if (ShutdownRequested()) { + break; + } std::pair<unsigned char, uint256> key; if (pcursor->GetKey(key) && key.first == DB_COINS) { + if (count++ % 256 == 0) { + uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1); + int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5); + uiInterface.ShowProgress(_("Upgrading UTXO database") + "\n"+ _("(press q to shutdown and continue later)") + "\n", percentageDone); + if (reportDone < percentageDone/10) { + // report max. every 10% step + LogPrintf("[%d%%]...", percentageDone); + reportDone = percentageDone/10; + } + } CCoins old_coins; if (!pcursor->GetValue(old_coins)) { return error("%s: cannot parse CCoins record", __func__); @@ -397,5 +416,7 @@ bool CCoinsViewDB::Upgrade() { } } db.WriteBatch(batch); + uiInterface.SetProgressBreakAction(std::function<void(void)>()); + LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE"); return true; } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index dcfc5ffde0..4a81055231 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -11,6 +11,7 @@ #include "validation.h" #include "policy/policy.h" #include "policy/fees.h" +#include "reverse_iterator.h" #include "streams.h" #include "timedata.h" #include "util.h" @@ -127,7 +128,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashes // This maximizes the benefit of the descendant cache and guarantees that // setMemPoolChildren will be updated, an assumption made in // UpdateForDescendants. - BOOST_REVERSE_FOREACH(const uint256 &hash, vHashesToUpdate) { + for (const uint256 &hash : reverse_iterate(vHashesToUpdate)) { // we cache the in-mempool children to avoid duplicate updates setEntries setChildren; // calculate children from mapNextTx diff --git a/src/ui_interface.h b/src/ui_interface.h index 090402aeed..762dd19b19 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -97,6 +97,9 @@ public: /** Show progress e.g. for verifychain */ boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress; + /** Set progress break action (possible "cancel button" triggers that action) */ + boost::signals2::signal<void (std::function<void(void)> action)> SetProgressBreakAction; + /** New block has been accepted */ boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip; diff --git a/src/validation.cpp b/src/validation.cpp index 0fe7f775af..09288be1ca 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -14,6 +14,7 @@ #include "consensus/merkle.h" #include "consensus/tx_verify.h" #include "consensus/validation.h" +#include "cuckoocache.h" #include "fs.h" #include "hash.h" #include "init.h" @@ -23,6 +24,7 @@ #include "primitives/block.h" #include "primitives/transaction.h" #include "random.h" +#include "reverse_iterator.h" #include "script/script.h" #include "script/sigcache.h" #include "script/standard.h" @@ -189,7 +191,7 @@ enum FlushStateMode { static bool FlushStateToDisk(const CChainParams& chainParams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight=0); static void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight); static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight); -static bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = NULL); +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr); static FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); bool CheckFinalTx(const CTransaction &tx, int flags) @@ -312,6 +314,9 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool return EvaluateSequenceLocks(index, lockPair); } +// Returns the script flags which should be checked for a given block +static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& chainparams); + static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) { int expired = pool.Expire(GetTime() - age); if (expired != 0) { @@ -395,6 +400,42 @@ void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool f LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); } +// Used to avoid mempool polluting consensus critical paths if CCoinsViewMempool +// were somehow broken and returning the wrong scriptPubKeys +static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, CTxMemPool& pool, + unsigned int flags, bool cacheSigStore, PrecomputedTransactionData& txdata) { + AssertLockHeld(cs_main); + + // pool.cs should be locked already, but go ahead and re-take the lock here + // to enforce that mempool doesn't change between when we check the view + // and when we actually call through to CheckInputs + LOCK(pool.cs); + + assert(!tx.IsCoinBase()); + for (const CTxIn& txin : tx.vin) { + const Coin& coin = view.AccessCoin(txin.prevout); + + // At this point we haven't actually checked if the coins are all + // available (or shouldn't assume we have, since CheckInputs does). + // So we just return failure if the inputs are not available here, + // and then only have to check equivalence for available inputs. + if (coin.IsSpent()) return false; + + const CTransactionRef& txFrom = pool.get(txin.prevout.hash); + if (txFrom) { + assert(txFrom->GetHash() == txin.prevout.hash); + assert(txFrom->vout.size() > txin.prevout.n); + assert(txFrom->vout[txin.prevout.n] == coin.out); + } else { + const Coin& coinFromDisk = pcoinsTip->AccessCoin(txin.prevout); + assert(!coinFromDisk.IsSpent()); + assert(coinFromDisk.out == coin.out); + } + } + + return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, txdata); +} + static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx, bool fLimitFree, bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector<COutPoint>& coins_to_uncache) @@ -751,32 +792,51 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. PrecomputedTransactionData txdata(tx); - if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, txdata)) { + if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false, txdata)) { // SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we // need to turn both off, and compare against just turning off CLEANSTACK // to see if the failure is specifically due to witness validation. CValidationState stateDummy; // Want reported failures to be from first CheckInputs - if (!tx.HasWitness() && CheckInputs(tx, stateDummy, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, txdata) && - !CheckInputs(tx, stateDummy, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, txdata)) { + if (!tx.HasWitness() && CheckInputs(tx, stateDummy, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, false, txdata) && + !CheckInputs(tx, stateDummy, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false, txdata)) { // Only the witness is missing, so the transaction itself may be fine. state.SetCorruptionPossible(); } return false; // state filled in by CheckInputs } - // Check again against just the consensus-critical mandatory script - // verification flags, in case of bugs in the standard flags that cause + // Check again against the current block tip's script verification + // flags to cache our script execution flags. This is, of course, + // useless if the next block has different script flags from the + // previous one, but because the cache tracks script flags for us it + // will auto-invalidate and we'll just have a few blocks of extra + // misses on soft-fork activation. + // + // This is also useful in case of bugs in the standard flags that cause // transactions to pass as valid when they're actually invalid. For // instance the STRICTENC flag was incorrectly allowing certain // CHECKSIG NOT scripts to pass, even though they were invalid. // // There is a similar check in CreateNewBlock() to prevent creating - // invalid blocks, however allowing such transactions into the mempool - // can be exploited as a DoS attack. - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata)) + // invalid blocks (using TestBlockValidity), however allowing such + // transactions into the mempool can be exploited as a DoS attack. + unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(chainActive.Tip(), Params().GetConsensus()); + if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, currentBlockScriptVerifyFlags, true, txdata)) { - return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s, %s", - __func__, hash.ToString(), FormatStateMessage(state)); + // If we're using promiscuousmempoolflags, we may hit this normally + // Check if current block has some flags that scriptVerifyFlags + // does not before printing an ominous warning + if (!(~scriptVerifyFlags & currentBlockScriptVerifyFlags)) { + return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against latest-block but not STANDARD flags %s, %s", + __func__, hash.ToString(), FormatStateMessage(state)); + } else { + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, false, txdata)) { + return error("%s: ConnectInputs failed against MANDATORY but not STANDARD flags due to promiscuous mempool %s, %s", + __func__, hash.ToString(), FormatStateMessage(state)); + } else { + LogPrintf("Warning: -promiscuousmempool flags set to not include currently enforced soft forks, this may break mining or otherwise cause instability!\n"); + } + } } // Remove conflicting transactions from the mempool @@ -1152,12 +1212,34 @@ int GetSpendHeight(const CCoinsViewCache& inputs) return pindexPrev->nHeight + 1; } + +static CuckooCache::cache<uint256, SignatureCacheHasher> scriptExecutionCache; +static uint256 scriptExecutionCacheNonce(GetRandHash()); + +void InitScriptExecutionCache() { + // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, + // setup_bytes creates the minimum possible cache (2 elements). + size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); + size_t nElems = scriptExecutionCache.setup_bytes(nMaxCacheSize); + LogPrintf("Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n", + (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems); +} + /** * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) - * This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it - * instead of being performed inline. + * This does not modify the UTXO set. + * + * If pvChecks is not NULL, script checks are pushed onto it instead of being performed inline. Any + * script checks which are not necessary (eg due to script execution cache hits) are, obviously, + * not pushed onto pvChecks/run. + * + * Setting cacheSigStore/cacheFullScriptStore to false will remove elements from the corresponding cache + * which are matched. This is useful for checking blocks where we will likely never need the cache + * entry again. + * + * Non-static (and re-declared) in src/test/txvalidationcache_tests.cpp */ -static bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks) +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks) { if (!tx.IsCoinBase()) { @@ -1177,6 +1259,21 @@ static bool CheckInputs(const CTransaction& tx, CValidationState &state, const C // Of course, if an assumed valid block is invalid due to false scriptSigs // this optimization would allow an invalid chain to be accepted. if (fScriptChecks) { + // First check if script executions have been cached with the same + // flags. Note that this assumes that the inputs provided are + // correct (ie that the transaction hash which is in tx's prevouts + // properly commits to the scriptPubKey in the inputs view of that + // transaction). + uint256 hashCacheEntry; + // We only use the first 19 bytes of nonce to avoid a second SHA + // round - giving us 19 + 32 + 4 = 55 bytes (+ 8 + 1 = 64) + static_assert(55 - sizeof(flags) - 32 >= 128/8, "Want at least 128 bits of nonce for script execution cache"); + CSHA256().Write(scriptExecutionCacheNonce.begin(), 55 - sizeof(flags) - 32).Write(tx.GetWitnessHash().begin(), 32).Write((unsigned char*)&flags, sizeof(flags)).Finalize(hashCacheEntry.begin()); + AssertLockHeld(cs_main); //TODO: Remove this requirement by making CuckooCache not require external locks + if (scriptExecutionCache.contains(hashCacheEntry, !cacheFullScriptStore)) { + return true; + } + for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; const Coin& coin = inputs.AccessCoin(prevout); @@ -1191,7 +1288,7 @@ static bool CheckInputs(const CTransaction& tx, CValidationState &state, const C const CAmount amount = coin.out.nValue; // Verify signature - CScriptCheck check(scriptPubKey, amount, tx, i, flags, cacheStore, &txdata); + CScriptCheck check(scriptPubKey, amount, tx, i, flags, cacheSigStore, &txdata); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -1204,7 +1301,7 @@ static bool CheckInputs(const CTransaction& tx, CValidationState &state, const C // avoid splitting the network between upgraded and // non-upgraded nodes. CScriptCheck check2(scriptPubKey, amount, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, &txdata); + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata); if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } @@ -1218,6 +1315,12 @@ static bool CheckInputs(const CTransaction& tx, CValidationState &state, const C return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError()))); } } + + if (cacheFullScriptStore && !pvChecks) { + // We executed all of the provided scripts, and were told to + // cache the result. Do so now. + scriptExecutionCache.insert(hashCacheEntry); + } } } @@ -1481,6 +1584,41 @@ public: // Protected by cs_main static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS]; +static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) { + AssertLockHeld(cs_main); + + // BIP16 didn't become active until Apr 1 2012 + int64_t nBIP16SwitchTime = 1333238400; + bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime); + + unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; + + // Start enforcing the DERSIG (BIP66) rule + if (pindex->nHeight >= consensusparams.BIP66Height) { + flags |= SCRIPT_VERIFY_DERSIG; + } + + // Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule + if (pindex->nHeight >= consensusparams.BIP65Height) { + flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; + } + + // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic. + if (VersionBitsState(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { + flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; + } + + // Start enforcing WITNESS rules using versionbits logic. + if (IsWitnessEnabled(pindex->pprev, consensusparams)) { + flags |= SCRIPT_VERIFY_WITNESS; + flags |= SCRIPT_VERIFY_NULLDUMMY; + } + + return flags; +} + + + static int64_t nTimeCheck = 0; static int64_t nTimeForks = 0; static int64_t nTimeVerify = 0; @@ -1584,34 +1722,14 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd } } - // BIP16 didn't become active until Apr 1 2012 - int64_t nBIP16SwitchTime = 1333238400; - bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime); - - unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; - - // Start enforcing the DERSIG (BIP66) rule - if (pindex->nHeight >= chainparams.GetConsensus().BIP66Height) { - flags |= SCRIPT_VERIFY_DERSIG; - } - - // Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule - if (pindex->nHeight >= chainparams.GetConsensus().BIP65Height) { - flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; - } - // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic. int nLockTimeFlags = 0; if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { - flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; } - // Start enforcing WITNESS rules using versionbits logic. - if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus())) { - flags |= SCRIPT_VERIFY_WITNESS; - flags |= SCRIPT_VERIFY_NULLDUMMY; - } + // Get the script flags for this block + unsigned int flags = GetBlockScriptFlags(pindex, chainparams.GetConsensus()); int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001); @@ -1672,7 +1790,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd std::vector<CScriptCheck> vChecks; bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */ - if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : NULL)) + if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : NULL)) return error("ConnectBlock(): CheckInputs on %s failed with %s", tx.GetHash().ToString(), FormatStateMessage(state)); control.Add(vChecks); @@ -2223,7 +2341,7 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c nHeight = nTargetHeight; // Connect new blocks. - BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { + for (CBlockIndex *pindexConnect : reverse_iterate(vpindexToConnect)) { if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) { if (state.IsInvalid()) { // The block violates a consensus rule. diff --git a/src/validation.h b/src/validation.h index 8a721dd7a2..a9f995abb8 100644 --- a/src/validation.h +++ b/src/validation.h @@ -393,6 +393,9 @@ public: ScriptError GetScriptError() const { return error; } }; +/** Initializes the script-execution cache */ +void InitScriptExecutionCache(); + /** Functions for disk access for blocks */ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 46d7c9b329..be2f20b863 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -21,12 +21,10 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); } void UnregisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); @@ -39,7 +37,6 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { } void UnregisterAllValidationInterfaces() { - g_signals.ScriptForMining.disconnect_all_slots(); g_signals.BlockChecked.disconnect_all_slots(); g_signals.Broadcast.disconnect_all_slots(); g_signals.Inventory.disconnect_all_slots(); diff --git a/src/validationinterface.h b/src/validationinterface.h index 460aecf243..17545018df 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -40,7 +40,6 @@ protected: virtual void Inventory(const uint256 &hash) {} virtual void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) {} virtual void BlockChecked(const CBlock&, const CValidationState&) {} - virtual void GetScriptForMining(std::shared_ptr<CReserveScript>&) {}; virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& block) {}; friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); @@ -72,8 +71,6 @@ struct CMainSignals { * callback was generated (not necessarily now) */ boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked; - /** Notifies listeners that a key for mining is required (coinbase) */ - boost::signals2::signal<void (std::shared_ptr<CReserveScript>&)> ScriptForMining; /** * Notifies listeners that a block which builds directly on our current tip * has been received and connected to the headers tree, though not validated yet */ diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 6fa685628f..dcce88cedc 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -12,7 +12,6 @@ #include <string> #include <vector> -#include <boost/foreach.hpp> int CCrypter::BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const { diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index c8928a3b66..da2d180756 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -18,7 +18,6 @@ #include <sys/stat.h> #endif -#include <boost/foreach.hpp> #include <boost/thread.hpp> // diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 0fe2412352..9f42b1f266 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -26,7 +26,6 @@ #include <univalue.h> -#include <boost/foreach.hpp> std::string static EncodeDumpTime(int64_t nTime) { return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); @@ -362,7 +361,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) "\nExamples:\n" + HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") + "\nAs a JSON-RPC call\n" - + HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") + + HelpExampleRpc("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") ); LOCK2(cs_main, pwallet->cs_wallet); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ebbde59972..867ccd4244 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -15,6 +15,7 @@ #include "policy/fees.h" #include "policy/policy.h" #include "policy/rbf.h" +#include "rpc/mining.h" #include "rpc/server.h" #include "script/sign.h" #include "timedata.h" @@ -2923,6 +2924,51 @@ UniValue bumpfee(const JSONRPCRequest& request) return result; } +UniValue generate(const JSONRPCRequest& request) +{ + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { + throw std::runtime_error( + "generate nblocks ( maxtries )\n" + "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n" + "\nArguments:\n" + "1. nblocks (numeric, required) How many blocks are generated immediately.\n" + "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" + "\nResult:\n" + "[ blockhashes ] (array) hashes of blocks generated\n" + "\nExamples:\n" + "\nGenerate 11 blocks\n" + + HelpExampleCli("generate", "11") + ); + } + + int num_generate = request.params[0].get_int(); + uint64_t max_tries = 1000000; + if (request.params.size() > 1 && !request.params[1].isNull()) { + max_tries = request.params[1].get_int(); + } + + std::shared_ptr<CReserveScript> coinbase_script; + pwallet->GetScriptForMining(coinbase_script); + + // If the keypool is exhausted, no script is returned at all. Catch this. + if (!coinbase_script) { + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + } + + //throw an error if no script was provided + if (coinbase_script->reserveScript.empty()) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available"); + } + + return generateBlocks(coinbase_script, num_generate, max_tries, true); +} + extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp extern UniValue importprivkey(const JSONRPCRequest& request); @@ -2986,6 +3032,8 @@ static const CRPCCommand commands[] = { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} }, { "wallet", "walletpassphrase", &walletpassphrase, true, {"passphrase","timeout"} }, { "wallet", "removeprunedfunds", &removeprunedfunds, true, {"txid"} }, + + { "generating", "generate", &generate, true, {"nblocks","maxtries"} }, }; void RegisterWalletRPCCommands(CRPCTable &t) diff --git a/src/wallet/test/accounting_tests.cpp b/src/wallet/test/accounting_tests.cpp index 12d9f2e995..330878ceb5 100644 --- a/src/wallet/test/accounting_tests.cpp +++ b/src/wallet/test/accounting_tests.cpp @@ -8,7 +8,6 @@ #include <stdint.h> -#include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> extern CWallet* pwalletMain; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a3fd7408a0..4f558adc77 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1025,7 +1025,7 @@ public: } } - void GetScriptForMining(std::shared_ptr<CReserveScript> &script) override; + void GetScriptForMining(std::shared_ptr<CReserveScript> &script); unsigned int GetKeyPoolSize() { diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 8321719b56..deb09a4771 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -18,7 +18,6 @@ #include <atomic> -#include <boost/foreach.hpp> #include <boost/thread.hpp> // |