aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/Makefile.test.include1
-rw-r--r--src/coincontrol.h3
-rw-r--r--src/core_memusage.h2
-rw-r--r--src/hash.h8
-rw-r--r--src/httprpc.cpp56
-rw-r--r--src/init.cpp4
-rw-r--r--src/main.cpp120
-rw-r--r--src/main.h10
-rw-r--r--src/memusage.h10
-rw-r--r--src/net.cpp6
-rw-r--r--src/net.h3
-rw-r--r--src/policy/policy.h2
-rw-r--r--src/prevector.h486
-rw-r--r--src/primitives/transaction.h4
-rw-r--r--src/qt/bitcoinstrings.cpp16
-rw-r--r--src/qt/clientmodel.cpp7
-rw-r--r--src/qt/coincontroldialog.cpp5
-rw-r--r--src/qt/locale/bitcoin_da.ts28
-rw-r--r--src/qt/locale/bitcoin_de.ts6
-rw-r--r--src/qt/locale/bitcoin_en.ts233
-rw-r--r--src/qt/locale/bitcoin_es.ts8
-rw-r--r--src/qt/locale/bitcoin_ja.ts24
-rw-r--r--src/qt/locale/bitcoin_ko_KR.ts98
-rw-r--r--src/qt/locale/bitcoin_nb.ts28
-rw-r--r--src/qt/locale/bitcoin_pl.ts46
-rw-r--r--src/qt/locale/bitcoin_pt_BR.ts52
-rw-r--r--src/qt/locale/bitcoin_ru.ts304
-rw-r--r--src/qt/locale/bitcoin_sv.ts52
-rw-r--r--src/qt/locale/bitcoin_zh_TW.ts46
-rw-r--r--src/qt/paymentrequestplus.cpp2
-rw-r--r--src/qt/sendcoinsdialog.cpp27
-rw-r--r--src/rpcrawtransaction.cpp3
-rw-r--r--src/script/interpreter.cpp2
-rw-r--r--src/script/script.cpp6
-rw-r--r--src/script/script.h14
-rw-r--r--src/script/sign.cpp4
-rw-r--r--src/serialize.h157
-rw-r--r--src/test/miner_tests.cpp26
-rw-r--r--src/test/prevector_tests.cpp217
-rw-r--r--src/test/rpc_tests.cpp1
-rw-r--r--src/test/script_P2SH_tests.cpp10
-rw-r--r--src/test/script_tests.cpp4
-rw-r--r--src/test/sigopcount_tests.cpp2
-rw-r--r--src/test/test_bitcoin.cpp2
-rw-r--r--src/test/test_bitcoin.h4
-rw-r--r--src/txmempool.cpp33
-rw-r--r--src/txmempool.h7
-rw-r--r--src/wallet/rpcwallet.cpp8
-rw-r--r--src/wallet/wallet.cpp104
-rw-r--r--src/wallet/wallet.h19
-rw-r--r--src/wallet/walletdb.cpp10
52 files changed, 1981 insertions, 350 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 40f2e19af0..bb627a5448 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -124,6 +124,7 @@ BITCOIN_CORE_H = \
policy/fees.h \
policy/policy.h \
pow.h \
+ prevector.h \
primitives/block.h \
primitives/transaction.h \
protocol.h \
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index c377183ad5..4d0894b711 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -65,6 +65,7 @@ BITCOIN_TESTS =\
test/pmt_tests.cpp \
test/policyestimator_tests.cpp \
test/pow_tests.cpp \
+ test/prevector_tests.cpp \
test/reverselock_tests.cpp \
test/rpc_tests.cpp \
test/sanity_tests.cpp \
diff --git a/src/coincontrol.h b/src/coincontrol.h
index bc965f9e19..3945644ce8 100644
--- a/src/coincontrol.h
+++ b/src/coincontrol.h
@@ -16,6 +16,8 @@ public:
bool fAllowOtherInputs;
//! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria
bool fAllowWatchOnly;
+ //! Minimum absolute fee (not per kilobyte)
+ CAmount nMinimumTotalFee;
CCoinControl()
{
@@ -28,6 +30,7 @@ public:
fAllowOtherInputs = false;
fAllowWatchOnly = false;
setSelected.clear();
+ nMinimumTotalFee = 0;
}
bool HasSelected() const
diff --git a/src/core_memusage.h b/src/core_memusage.h
index a05f59ee0c..450537d059 100644
--- a/src/core_memusage.h
+++ b/src/core_memusage.h
@@ -10,7 +10,7 @@
#include "memusage.h"
static inline size_t RecursiveDynamicUsage(const CScript& script) {
- return memusage::DynamicUsage(*static_cast<const std::vector<unsigned char>*>(&script));
+ return memusage::DynamicUsage(*static_cast<const CScriptBase*>(&script));
}
static inline size_t RecursiveDynamicUsage(const COutPoint& out) {
diff --git a/src/hash.h b/src/hash.h
index 0771555623..daa92a0097 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -8,6 +8,7 @@
#include "crypto/ripemd160.h"
#include "crypto/sha256.h"
+#include "prevector.h"
#include "serialize.h"
#include "uint256.h"
#include "version.h"
@@ -118,6 +119,13 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch)
return Hash160(vch.begin(), vch.end());
}
+/** Compute the 160-bit hash of a vector. */
+template<unsigned int N>
+inline uint160 Hash160(const prevector<N, unsigned char>& vch)
+{
+ return Hash160(vch.begin(), vch.end());
+}
+
/** A writer stream (for serialization) that computes a 256-bit hash. */
class CHashWriter
{
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index 98ac750bb1..2920aa26f7 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -10,8 +10,12 @@
#include "util.h"
#include "utilstrencodings.h"
#include "ui_interface.h"
+#include "crypto/hmac_sha256.h"
+#include <stdio.h>
+#include "utilstrencodings.h"
#include <boost/algorithm/string.hpp> // boost::trim
+#include <boost/foreach.hpp> //BOOST_FOREACH
/** Simple one-shot callback timer to be used by the RPC mechanism to e.g.
* re-lock the wellet.
@@ -72,6 +76,50 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni
req->WriteReply(nStatus, strReply);
}
+//This function checks username and password against -rpcauth
+//entries from config file.
+static bool multiUserAuthorized(std::string strUserPass)
+{
+ if (strUserPass.find(":") == std::string::npos) {
+ return false;
+ }
+ std::string strUser = strUserPass.substr(0, strUserPass.find(":"));
+ std::string strPass = strUserPass.substr(strUserPass.find(":") + 1);
+
+ if (mapMultiArgs.count("-rpcauth") > 0) {
+ //Search for multi-user login/pass "rpcauth" from config
+ BOOST_FOREACH(std::string strRPCAuth, mapMultiArgs["-rpcauth"])
+ {
+ std::vector<std::string> vFields;
+ boost::split(vFields, strRPCAuth, boost::is_any_of(":$"));
+ if (vFields.size() != 3) {
+ //Incorrect formatting in config file
+ continue;
+ }
+
+ std::string strName = vFields[0];
+ if (!TimingResistantEqual(strName, strUser)) {
+ continue;
+ }
+
+ std::string strSalt = vFields[1];
+ std::string strHash = vFields[2];
+
+ unsigned int KEY_SIZE = 32;
+ unsigned char *out = new unsigned char[KEY_SIZE];
+
+ CHMAC_SHA256(reinterpret_cast<const unsigned char*>(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast<const unsigned char*>(strPass.c_str()), strPass.size()).Finalize(out);
+ std::vector<unsigned char> hexvec(out, out+KEY_SIZE);
+ std::string strHashFromPass = HexStr(hexvec);
+
+ if (TimingResistantEqual(strHashFromPass, strHash)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
static bool RPCAuthorized(const std::string& strAuth)
{
if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called
@@ -81,7 +129,12 @@ static bool RPCAuthorized(const std::string& strAuth)
std::string strUserPass64 = strAuth.substr(6);
boost::trim(strUserPass64);
std::string strUserPass = DecodeBase64(strUserPass64);
- return TimingResistantEqual(strUserPass, strRPCUserColonPass);
+
+ //Check if authorized under single-user field
+ if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) {
+ return true;
+ }
+ return multiUserAuthorized(strUserPass);
}
static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &)
@@ -157,6 +210,7 @@ static bool InitRPCAuthentication()
return false;
}
} else {
+ LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.");
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
}
return true;
diff --git a/src/init.cpp b/src/init.cpp
index 01c7189675..c36cf9efbc 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -393,8 +393,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageGroup(_("Wallet options:"));
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE));
- if (showDebug)
- strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
+ strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"),
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
@@ -491,6 +490,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-rpcbind=<addr>", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)"));
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcauth=<userpw>", _("Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times"));
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"));
strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS));
diff --git a/src/main.cpp b/src/main.cpp
index 55b0517349..e3c77e8505 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -953,7 +953,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
CAmount inChainInputValue;
double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue);
- CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue);
+ // Keep track of transactions that spend a coinbase, which we re-scan
+ // during reorgs to ensure COINBASE_MATURITY is still met.
+ bool fSpendsCoinbase = false;
+ BOOST_FOREACH(const CTxIn &txin, tx.vin) {
+ const CCoins *coins = view.AccessCoins(txin.prevout.hash);
+ if (coins->IsCoinBase()) {
+ fSpendsCoinbase = true;
+ break;
+ }
+ }
+
+ CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase);
unsigned int nSize = entry.GetTxSize();
// Don't accept it if it can't get into a block
@@ -2310,12 +2321,11 @@ void static UpdateTip(CBlockIndex *pindexNew) {
}
}
-/** Disconnect chainActive's tip. You want to manually re-limit mempool size after this */
+/** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */
bool static DisconnectTip(CValidationState& state, const Consensus::Params& consensusParams)
{
CBlockIndex *pindexDelete = chainActive.Tip();
assert(pindexDelete);
- mempool.check(pcoinsTip);
// Read block from disk.
CBlock block;
if (!ReadBlockFromDisk(block, pindexDelete, consensusParams))
@@ -2350,8 +2360,6 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons
// UpdateTransactionsFromBlock finds descendants of any transactions in this
// block that were added back and cleans up the mempool state.
mempool.UpdateTransactionsFromBlock(vHashUpdate);
- mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
- mempool.check(pcoinsTip);
// Update chainActive and related variables.
UpdateTip(pindexDelete->pprev);
// Let wallets know transactions went from 1-confirmed to
@@ -2375,7 +2383,6 @@ static int64_t nTimePostConnect = 0;
bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock)
{
assert(pindexNew->pprev == chainActive.Tip());
- mempool.check(pcoinsTip);
// Read block from disk.
int64_t nTime1 = GetTimeMicros();
CBlock block;
@@ -2412,7 +2419,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
// Remove conflicting transactions from the mempool.
list<CTransaction> txConflicted;
mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload());
- mempool.check(pcoinsTip);
// Update chainActive & related variables.
UpdateTip(pindexNew);
// Tell wallet about transactions that went from mempool
@@ -2525,46 +2531,49 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
bool fContinue = true;
int nHeight = pindexFork ? pindexFork->nHeight : -1;
while (fContinue && nHeight != pindexMostWork->nHeight) {
- // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
- // a few blocks along the way.
- int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
- vpindexToConnect.clear();
- vpindexToConnect.reserve(nTargetHeight - nHeight);
- CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
- while (pindexIter && pindexIter->nHeight != nHeight) {
- vpindexToConnect.push_back(pindexIter);
- pindexIter = pindexIter->pprev;
- }
- nHeight = nTargetHeight;
-
- // Connect new blocks.
- BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
- if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
- if (state.IsInvalid()) {
- // The block violates a consensus rule.
- if (!state.CorruptionPossible())
- InvalidChainFound(vpindexToConnect.back());
- state = CValidationState();
- fInvalidFound = true;
- fContinue = false;
- break;
+ // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
+ // a few blocks along the way.
+ int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
+ vpindexToConnect.clear();
+ vpindexToConnect.reserve(nTargetHeight - nHeight);
+ CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
+ while (pindexIter && pindexIter->nHeight != nHeight) {
+ vpindexToConnect.push_back(pindexIter);
+ pindexIter = pindexIter->pprev;
+ }
+ nHeight = nTargetHeight;
+
+ // Connect new blocks.
+ BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
+ if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
+ if (state.IsInvalid()) {
+ // The block violates a consensus rule.
+ if (!state.CorruptionPossible())
+ InvalidChainFound(vpindexToConnect.back());
+ state = CValidationState();
+ fInvalidFound = true;
+ fContinue = false;
+ break;
+ } else {
+ // A system error occurred (disk space, database error, ...).
+ return false;
+ }
} else {
- // A system error occurred (disk space, database error, ...).
- return false;
- }
- } else {
- PruneBlockIndexCandidates();
- if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
- // We're in a better position than we were. Return temporarily to release the lock.
- fContinue = false;
- break;
+ PruneBlockIndexCandidates();
+ if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
+ // We're in a better position than we were. Return temporarily to release the lock.
+ fContinue = false;
+ break;
+ }
}
}
}
- }
- if (fBlocksDisconnected)
+ if (fBlocksDisconnected) {
+ mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
+ }
+ mempool.check(pcoinsTip);
// Callbacks/notifications for a new best chain.
if (fInvalidFound)
@@ -2672,6 +2681,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
// ActivateBestChain considers blocks already in chainActive
// unconditionally valid already, so force disconnect away from it.
if (!DisconnectTip(state, consensusParams)) {
+ mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
return false;
}
}
@@ -2689,6 +2699,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
}
InvalidChainFound(pindex);
+ mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
return true;
}
@@ -3979,29 +3990,34 @@ std::string GetWarnings(const std::string& strFor)
int nPriority = 0;
string strStatusBar;
string strRPC;
+ string strGUI;
- if (!CLIENT_VERSION_IS_RELEASE)
- strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
+ if (!CLIENT_VERSION_IS_RELEASE) {
+ strStatusBar = "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications";
+ strGUI = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
+ }
if (GetBoolArg("-testsafemode", DEFAULT_TESTSAFEMODE))
- strStatusBar = strRPC = "testsafemode enabled";
+ strStatusBar = strRPC = strGUI = "testsafemode enabled";
// Misc warnings like out of disk space and clock is wrong
if (strMiscWarning != "")
{
nPriority = 1000;
- strStatusBar = strMiscWarning;
+ strStatusBar = strGUI = strMiscWarning;
}
if (fLargeWorkForkFound)
{
nPriority = 2000;
- strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
+ strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.";
+ strGUI = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
}
else if (fLargeWorkInvalidChainFound)
{
nPriority = 2000;
- strStatusBar = strRPC = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.");
+ strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.";
+ strGUI = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.");
}
// Alerts
@@ -4013,12 +4029,14 @@ std::string GetWarnings(const std::string& strFor)
if (alert.AppliesToMe() && alert.nPriority > nPriority)
{
nPriority = alert.nPriority;
- strStatusBar = alert.strStatusBar;
+ strStatusBar = strGUI = alert.strStatusBar;
}
}
}
- if (strFor == "statusbar")
+ if (strFor == "gui")
+ return strGUI;
+ else if (strFor == "statusbar")
return strStatusBar;
else if (strFor == "rpc")
return strRPC;
@@ -4675,6 +4693,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
bool fMissingInputs = false;
CValidationState state;
+ pfrom->setAskFor.erase(inv.hash);
mapAlreadyAskedFor.erase(inv);
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
@@ -5623,6 +5642,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
pto->PushMessage("getdata", vGetData);
vGetData.clear();
}
+ } else {
+ //If we're not going to ask, don't expect a response.
+ pto->setAskFor.erase(inv.hash);
}
pto->mapAskFor.erase(pto->mapAskFor.begin());
}
diff --git a/src/main.h b/src/main.h
index bdbfa3826e..16dff28363 100644
--- a/src/main.h
+++ b/src/main.h
@@ -206,7 +206,13 @@ void ThreadScriptCheck();
void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing);
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
bool IsInitialBlockDownload();
-/** Format a string that describes several potential problems detected by the core */
+/** Format a string that describes several potential problems detected by the core.
+ * strFor can have three values:
+ * - "rpc": get critical warnings, which should put the client in safe mode if non-empty
+ * - "statusbar": get all warnings
+ * - "gui": get all warnings, translated (where possible) for GUI
+ * This function only returns the highest priority warning of the set selected by strFor.
+ */
std::string GetWarnings(const std::string& strFor);
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
bool GetTransaction(const uint256 &hash, CTransaction &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false);
@@ -467,7 +473,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
/** Remove invalidity status from a block and its descendants. */
bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex);
-/** The currently-connected chain of blocks. */
+/** The currently-connected chain of blocks (protected by cs_main). */
extern CChain chainActive;
/** Global variable that points to the active CCoinsView (protected by cs_main) */
diff --git a/src/memusage.h b/src/memusage.h
index e96c5bf038..49760e64c7 100644
--- a/src/memusage.h
+++ b/src/memusage.h
@@ -46,7 +46,9 @@ template<typename X> static inline size_t DynamicUsage(const X * const &v) { ret
static inline size_t MallocUsage(size_t alloc)
{
// Measured on libc6 2.19 on Linux.
- if (sizeof(void*) == 8) {
+ if (alloc == 0) {
+ return 0;
+ } else if (sizeof(void*) == 8) {
return ((alloc + 31) >> 4) << 4;
} else if (sizeof(void*) == 4) {
return ((alloc + 15) >> 3) << 3;
@@ -74,6 +76,12 @@ static inline size_t DynamicUsage(const std::vector<X>& v)
return MallocUsage(v.capacity() * sizeof(X));
}
+template<unsigned int N, typename X, typename S, typename D>
+static inline size_t DynamicUsage(const prevector<N, X, S, D>& v)
+{
+ return MallocUsage(v.allocated_memory());
+}
+
template<typename X, typename Y>
static inline size_t DynamicUsage(const std::set<X, Y>& s)
{
diff --git a/src/net.cpp b/src/net.cpp
index abc7cbb8f4..e5659efc01 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2407,8 +2407,12 @@ CNode::~CNode()
void CNode::AskFor(const CInv& inv)
{
- if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
+ if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
return;
+ // a peer may not have multiple non-responded queue positions for a single inv item
+ if (!setAskFor.insert(inv.hash).second)
+ return;
+
// We're using mapAskFor as a priority queue,
// the key is the earliest time the request can be sent
int64_t nRequestTime;
diff --git a/src/net.h b/src/net.h
index fb299fb0b4..a5a5c770d6 100644
--- a/src/net.h
+++ b/src/net.h
@@ -58,6 +58,8 @@ static const bool DEFAULT_UPNP = false;
#endif
/** The maximum number of entries in mapAskFor */
static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
+/** The maximum number of entries in setAskFor (larger due to getdata latency)*/
+static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
/** The maximum number of peer connections to maintain. */
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
/** The default for -maxuploadtarget. 0 = Unlimited */
@@ -389,6 +391,7 @@ public:
mruset<CInv> setInventoryKnown;
std::vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory;
+ std::set<uint256> setAskFor;
std::multimap<int64_t, CInv> mapAskFor;
// Used for headers announcements - unfiltered blocks to relay
// Also protected by cs_inventory
diff --git a/src/policy/policy.h b/src/policy/policy.h
index c8d2c1a924..31655f2f3a 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -18,7 +18,7 @@ class CCoinsViewCache;
static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000;
static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0;
/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
-static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000;
+static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0;
/** The maximum size for transactions we're willing to relay/mine */
static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
/** Maximum number of signature check operations in an IsStandard() P2SH script */
diff --git a/src/prevector.h b/src/prevector.h
new file mode 100644
index 0000000000..3e80ef5d33
--- /dev/null
+++ b/src/prevector.h
@@ -0,0 +1,486 @@
+#ifndef _BITCOIN_PREVECTOR_H_
+#define _BITCOIN_PREVECTOR_H_
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <iterator>
+
+#pragma pack(push, 1)
+/** Implements a drop-in replacement for std::vector<T> which stores up to N
+ * elements directly (without heap allocation). The types Size and Diff are
+ * used to store element counts, and can be any unsigned + signed type.
+ *
+ * Storage layout is either:
+ * - Direct allocation:
+ * - Size _size: the number of used elements (between 0 and N)
+ * - T direct[N]: an array of N elements of type T
+ * (only the first _size are initialized).
+ * - Indirect allocation:
+ * - Size _size: the number of used elements plus N + 1
+ * - Size capacity: the number of allocated elements
+ * - T* indirect: a pointer to an array of capacity elements of type T
+ * (only the first _size are initialized).
+ *
+ * The data type T must be movable by memmove/realloc(). Once we switch to C++,
+ * move constructors can be used instead.
+ */
+template<unsigned int N, typename T, typename Size = uint32_t, typename Diff = int32_t>
+class prevector {
+public:
+ typedef Size size_type;
+ typedef Diff difference_type;
+ typedef T value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ class iterator {
+ T* ptr;
+ public:
+ typedef Diff difference_type;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+ iterator(T* ptr_) : ptr(ptr_) {}
+ T& operator*() const { return *ptr; }
+ T* operator->() const { return ptr; }
+ T& operator[](size_type pos) { return ptr[pos]; }
+ const T& operator[](size_type pos) const { return ptr[pos]; }
+ iterator& operator++() { ptr++; return *this; }
+ iterator& operator--() { ptr--; return *this; }
+ iterator operator++(int) { iterator copy(*this); ++(*this); return copy; }
+ iterator operator--(int) { iterator copy(*this); --(*this); return copy; }
+ difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); }
+ iterator operator+(size_type n) { return iterator(ptr + n); }
+ iterator& operator+=(size_type n) { ptr += n; return *this; }
+ iterator operator-(size_type n) { return iterator(ptr - n); }
+ iterator& operator-=(size_type n) { ptr -= n; return *this; }
+ bool operator==(iterator x) const { return ptr == x.ptr; }
+ bool operator!=(iterator x) const { return ptr != x.ptr; }
+ bool operator>=(iterator x) const { return ptr >= x.ptr; }
+ bool operator<=(iterator x) const { return ptr <= x.ptr; }
+ bool operator>(iterator x) const { return ptr > x.ptr; }
+ bool operator<(iterator x) const { return ptr < x.ptr; }
+ };
+
+ class reverse_iterator {
+ T* ptr;
+ public:
+ typedef Diff difference_type;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ reverse_iterator(T* ptr_) : ptr(ptr_) {}
+ T& operator*() { return *ptr; }
+ const T& operator*() const { return *ptr; }
+ T* operator->() { return ptr; }
+ const T* operator->() const { return ptr; }
+ reverse_iterator& operator--() { ptr++; return *this; }
+ reverse_iterator& operator++() { ptr--; return *this; }
+ reverse_iterator operator++(int) { reverse_iterator copy(*this); ++(*this); return copy; }
+ reverse_iterator operator--(int) { reverse_iterator copy(*this); --(*this); return copy; }
+ bool operator==(reverse_iterator x) const { return ptr == x.ptr; }
+ bool operator!=(reverse_iterator x) const { return ptr != x.ptr; }
+ };
+
+ class const_iterator {
+ const T* ptr;
+ public:
+ typedef Diff difference_type;
+ typedef const T value_type;
+ typedef const T* pointer;
+ typedef const T& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+ const_iterator(const T* ptr_) : ptr(ptr_) {}
+ const_iterator(iterator x) : ptr(&(*x)) {}
+ const T& operator*() const { return *ptr; }
+ const T* operator->() const { return ptr; }
+ const T& operator[](size_type pos) const { return ptr[pos]; }
+ const_iterator& operator++() { ptr++; return *this; }
+ const_iterator& operator--() { ptr--; return *this; }
+ const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; }
+ const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; }
+ difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); }
+ const_iterator operator+(size_type n) { return const_iterator(ptr + n); }
+ const_iterator& operator+=(size_type n) { ptr += n; return *this; }
+ const_iterator operator-(size_type n) { return const_iterator(ptr - n); }
+ const_iterator& operator-=(size_type n) { ptr -= n; return *this; }
+ bool operator==(const_iterator x) const { return ptr == x.ptr; }
+ bool operator!=(const_iterator x) const { return ptr != x.ptr; }
+ bool operator>=(const_iterator x) const { return ptr >= x.ptr; }
+ bool operator<=(const_iterator x) const { return ptr <= x.ptr; }
+ bool operator>(const_iterator x) const { return ptr > x.ptr; }
+ bool operator<(const_iterator x) const { return ptr < x.ptr; }
+ };
+
+ class const_reverse_iterator {
+ const T* ptr;
+ public:
+ typedef Diff difference_type;
+ typedef const T value_type;
+ 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(reverse_iterator x) : ptr(&(*x)) {}
+ const T& operator*() const { return *ptr; }
+ const T* operator->() const { return ptr; }
+ const_reverse_iterator& operator--() { ptr++; return *this; }
+ const_reverse_iterator& operator++() { ptr--; return *this; }
+ const_reverse_iterator operator++(int) { const_reverse_iterator copy(*this); ++(*this); return copy; }
+ const_reverse_iterator operator--(int) { const_reverse_iterator copy(*this); --(*this); return copy; }
+ bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; }
+ bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; }
+ };
+
+private:
+ size_type _size;
+ union {
+ char direct[sizeof(T) * N];
+ struct {
+ size_type capacity;
+ char* indirect;
+ };
+ } _union;
+
+ T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; }
+ const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; }
+ T* indirect_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.indirect) + pos; }
+ const T* indirect_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.indirect) + pos; }
+ bool is_direct() const { return _size <= N; }
+
+ void change_capacity(size_type new_capacity) {
+ if (new_capacity <= N) {
+ if (!is_direct()) {
+ T* indirect = indirect_ptr(0);
+ T* src = indirect;
+ T* dst = direct_ptr(0);
+ memcpy(dst, src, size() * sizeof(T));
+ free(indirect);
+ _size -= N + 1;
+ }
+ } else {
+ if (!is_direct()) {
+ _union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity));
+ _union.capacity = new_capacity;
+ } else {
+ char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity));
+ T* src = direct_ptr(0);
+ T* dst = reinterpret_cast<T*>(new_indirect);
+ memcpy(dst, src, size() * sizeof(T));
+ _union.indirect = new_indirect;
+ _union.capacity = new_capacity;
+ _size += N + 1;
+ }
+ }
+ }
+
+ T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
+ const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
+
+public:
+ void assign(size_type n, const T& val) {
+ clear();
+ if (capacity() < n) {
+ change_capacity(n);
+ }
+ while (size() < n) {
+ _size++;
+ new(static_cast<void*>(item_ptr(size() - 1))) T(val);
+ }
+ }
+
+ template<typename InputIterator>
+ void assign(InputIterator first, InputIterator last) {
+ size_type n = last - first;
+ clear();
+ if (capacity() < n) {
+ change_capacity(n);
+ }
+ while (first != last) {
+ _size++;
+ new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
+ ++first;
+ }
+ }
+
+ prevector() : _size(0) {}
+
+ explicit prevector(size_type n) : _size(0) {
+ resize(n);
+ }
+
+ explicit prevector(size_type n, const T& val = T()) : _size(0) {
+ change_capacity(n);
+ while (size() < n) {
+ _size++;
+ new(static_cast<void*>(item_ptr(size() - 1))) T(val);
+ }
+ }
+
+ template<typename InputIterator>
+ prevector(InputIterator first, InputIterator last) : _size(0) {
+ size_type n = last - first;
+ change_capacity(n);
+ while (first != last) {
+ _size++;
+ new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
+ ++first;
+ }
+ }
+
+ prevector(const prevector<N, T, Size, Diff>& other) : _size(0) {
+ change_capacity(other.size());
+ const_iterator it = other.begin();
+ while (it != other.end()) {
+ _size++;
+ new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
+ ++it;
+ }
+ }
+
+ prevector& operator=(const prevector<N, T, Size, Diff>& other) {
+ if (&other == this) {
+ return *this;
+ }
+ resize(0);
+ change_capacity(other.size());
+ const_iterator it = other.begin();
+ while (it != other.end()) {
+ _size++;
+ new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
+ ++it;
+ }
+ return *this;
+ }
+
+ size_type size() const {
+ return is_direct() ? _size : _size - N - 1;
+ }
+
+ bool empty() const {
+ return size() == 0;
+ }
+
+ iterator begin() { return iterator(item_ptr(0)); }
+ const_iterator begin() const { return const_iterator(item_ptr(0)); }
+ iterator end() { return iterator(item_ptr(size())); }
+ const_iterator end() const { return const_iterator(item_ptr(size())); }
+
+ reverse_iterator rbegin() { return reverse_iterator(item_ptr(size() - 1)); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(item_ptr(size() - 1)); }
+ reverse_iterator rend() { return reverse_iterator(item_ptr(-1)); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(item_ptr(-1)); }
+
+ size_t capacity() const {
+ if (is_direct()) {
+ return N;
+ } else {
+ return _union.capacity;
+ }
+ }
+
+ T& operator[](size_type pos) {
+ return *item_ptr(pos);
+ }
+
+ const T& operator[](size_type pos) const {
+ return *item_ptr(pos);
+ }
+
+ void resize(size_type new_size) {
+ while (size() > new_size) {
+ item_ptr(size() - 1)->~T();
+ _size--;
+ }
+ if (new_size > capacity()) {
+ change_capacity(new_size);
+ }
+ while (size() < new_size) {
+ _size++;
+ new(static_cast<void*>(item_ptr(size() - 1))) T();
+ }
+ }
+
+ void reserve(size_type new_capacity) {
+ if (new_capacity > capacity()) {
+ change_capacity(new_capacity);
+ }
+ }
+
+ void shrink_to_fit() {
+ change_capacity(size());
+ }
+
+ void clear() {
+ resize(0);
+ }
+
+ iterator insert(iterator pos, const T& value) {
+ size_type p = pos - begin();
+ size_type new_size = size() + 1;
+ if (capacity() < new_size) {
+ change_capacity(new_size + (new_size >> 1));
+ }
+ memmove(item_ptr(p + 1), item_ptr(p), (size() - p) * sizeof(T));
+ _size++;
+ new(static_cast<void*>(item_ptr(p))) T(value);
+ return iterator(item_ptr(p));
+ }
+
+ void insert(iterator pos, size_type count, const T& value) {
+ size_type p = pos - begin();
+ size_type new_size = size() + count;
+ if (capacity() < new_size) {
+ change_capacity(new_size + (new_size >> 1));
+ }
+ memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
+ _size += count;
+ for (size_type i = 0; i < count; i++) {
+ new(static_cast<void*>(item_ptr(p + i))) T(value);
+ }
+ }
+
+ template<typename InputIterator>
+ void insert(iterator pos, InputIterator first, InputIterator last) {
+ size_type p = pos - begin();
+ difference_type count = last - first;
+ size_type new_size = size() + count;
+ if (capacity() < new_size) {
+ change_capacity(new_size + (new_size >> 1));
+ }
+ memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
+ _size += count;
+ while (first != last) {
+ new(static_cast<void*>(item_ptr(p))) T(*first);
+ ++p;
+ ++first;
+ }
+ }
+
+ iterator erase(iterator pos) {
+ (*pos).~T();
+ memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos))));
+ _size--;
+ return pos;
+ }
+
+ iterator erase(iterator first, iterator last) {
+ iterator p = first;
+ char* endp = (char*)&(*end());
+ while (p != last) {
+ (*p).~T();
+ _size--;
+ ++p;
+ }
+ memmove(&(*first), &(*last), endp - ((char*)(&(*last))));
+ return first;
+ }
+
+ void push_back(const T& value) {
+ size_type new_size = size() + 1;
+ if (capacity() < new_size) {
+ change_capacity(new_size + (new_size >> 1));
+ }
+ new(item_ptr(size())) T(value);
+ _size++;
+ }
+
+ void pop_back() {
+ _size--;
+ }
+
+ T& front() {
+ return *item_ptr(0);
+ }
+
+ const T& front() const {
+ return *item_ptr(0);
+ }
+
+ T& back() {
+ return *item_ptr(size() - 1);
+ }
+
+ const T& back() const {
+ return *item_ptr(size() - 1);
+ }
+
+ void swap(prevector<N, T, Size, Diff>& other) {
+ if (_size & other._size & 1) {
+ std::swap(_union.capacity, other._union.capacity);
+ std::swap(_union.indirect, other._union.indirect);
+ } else {
+ std::swap(_union, other._union);
+ }
+ std::swap(_size, other._size);
+ }
+
+ ~prevector() {
+ clear();
+ if (!is_direct()) {
+ free(_union.indirect);
+ _union.indirect = NULL;
+ }
+ }
+
+ bool operator==(const prevector<N, T, Size, Diff>& other) const {
+ if (other.size() != size()) {
+ return false;
+ }
+ const_iterator b1 = begin();
+ const_iterator b2 = other.begin();
+ const_iterator e1 = end();
+ while (b1 != e1) {
+ if ((*b1) != (*b2)) {
+ return false;
+ }
+ ++b1;
+ ++b2;
+ }
+ return true;
+ }
+
+ bool operator!=(const prevector<N, T, Size, Diff>& other) const {
+ return !(*this == other);
+ }
+
+ bool operator<(const prevector<N, T, Size, Diff>& other) const {
+ if (size() < other.size()) {
+ return true;
+ }
+ if (size() > other.size()) {
+ return false;
+ }
+ const_iterator b1 = begin();
+ const_iterator b2 = other.begin();
+ const_iterator e1 = end();
+ while (b1 != e1) {
+ if ((*b1) < (*b2)) {
+ return true;
+ }
+ if ((*b2) < (*b1)) {
+ return false;
+ }
+ ++b1;
+ ++b2;
+ }
+ return false;
+ }
+
+ size_t allocated_memory() const {
+ if (is_direct()) {
+ return 0;
+ } else {
+ return ((size_t)(sizeof(T))) * _union.capacity;
+ }
+ }
+};
+#pragma pack(pop)
+
+#endif
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 98882d315e..c5d8a64a6d 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -74,7 +74,7 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(prevout);
- READWRITE(scriptSig);
+ READWRITE(*(CScriptBase*)(&scriptSig));
READWRITE(nSequence);
}
@@ -119,7 +119,7 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(nValue);
- READWRITE(scriptPubKey);
+ READWRITE(*(CScriptBase*)(&scriptPubKey));
}
void SetNull()
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 2449046538..6b5f243668 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -67,6 +67,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Fees (in %s/kB) smaller than this are considered zero fee for relaying, "
"mining and transaction creation (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Fees (in %s/kB) smaller than this are considered zero fee for transaction "
+"creation (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"If <category> is not supplied or if <category> = 1, output all debugging "
@@ -121,6 +124,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set the number of threads for coin generation if enabled (-1 = all cores, "
"default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Support filtering of blocks and transaction with bloom filters (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"The block database contains a block which appears to be from the future. "
"This may be due to your computer's date and time being set incorrectly. Only "
"rebuild the block database if you are sure that your computer's date and "
@@ -152,6 +157,10 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
"%s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Username and hashed password for JSON-RPC connections. The field <userpw> "
+"comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is "
+"included in share/rpcuser. This option can be specified multiple times"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"WARNING: abnormally high number of blocks generated, %d blocks received in "
"the last %d hours (%d expected)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -178,7 +187,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"mode. This will redownload the entire blockchain"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"),
QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
@@ -197,7 +205,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -whitebind address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Choose data directory on startup (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
@@ -274,15 +281,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
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", "Set SSL root certificates for payment request (default: -system-)"),
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)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: %s)"),
@@ -292,7 +296,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"),
QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
@@ -303,7 +306,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
-QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to start HTTP server. See debug log for details."),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index d36d129c1a..1271187420 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -158,7 +158,7 @@ enum BlockSource ClientModel::getBlockSource() const
QString ClientModel::getStatusBarWarnings() const
{
- return QString::fromStdString(GetWarnings("statusbar"));
+ return QString::fromStdString(GetWarnings("gui"));
}
OptionsModel *ClientModel::getOptionsModel()
@@ -253,7 +253,10 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB
// if we are in-sync, update the UI regardless of last update time
if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) {
//pass a async signal to the UI thread
- Q_EMIT clientmodel->numBlocksChanged(pIndex->nHeight, QDateTime::fromTime_t(pIndex->GetBlockTime()), clientmodel->getVerificationProgress(pIndex));
+ QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
+ Q_ARG(int, pIndex->nHeight),
+ Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
+ Q_ARG(double, clientmodel->getVerificationProgress(pIndex)));
nLastBlockTipUpdateNotification = now;
}
}
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index cbc41f3416..0f42243047 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -549,6 +549,9 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
// Fee
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
+ if (nPayFee > 0 && coinControl->nMinimumTotalFee > nPayFee)
+ nPayFee = coinControl->nMinimumTotalFee;
+
// Allow free? (require at least hard-coded threshold and default to that if no estimate)
double dPriorityNeeded = std::max(mempoolEstimatePriority, AllowFreeThreshold());
@@ -619,7 +622,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
l6->setText(sPriorityLabel); // Priority
l7->setText(fDust ? tr("yes") : tr("no")); // Dust
l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change
- if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000))
+ if (nPayFee > 0 && (coinControl->nMinimumTotalFee < nPayFee))
{
l3->setText(ASYMP_UTF8 + l3->text());
l4->setText(ASYMP_UTF8 + l4->text());
diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts
index 93594dcb05..ac194e0520 100644
--- a/src/qt/locale/bitcoin_da.ts
+++ b/src/qt/locale/bitcoin_da.ts
@@ -1097,7 +1097,7 @@
</message>
<message>
<source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source>
- <translation>Forbind til Bitcoin-netværket gennem en separat SOCKS5-proxy for skjulte tjenester via Tor.</translation>
+ <translation>Forbind til Bitcoin-netværket gennem en separat SOCKS5-proxy for skjulte Tor-tjenester.</translation>
</message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source>
@@ -2733,6 +2733,10 @@
<translation>Kopiér transaktions-ID</translation>
</message>
<message>
+ <source>Copy raw transaction</source>
+ <translation>Kopiér rå transaktion</translation>
+ </message>
+ <message>
<source>Edit label</source>
<translation>Redigér mærkat</translation>
</message>
@@ -3252,10 +3256,18 @@
<translation>Aktiverer bedste kæde…</translation>
</message>
<message>
+ <source>Always relay transactions received from whitelisted peers (default: %d)</source>
+ <translation>Videresend altid transaktioner, der modtages fra hvidlistede knuder (standard: %d)</translation>
+ </message>
+ <message>
<source>Attempt to recover private keys from a corrupt wallet.dat on startup</source>
<translation>Forsøg at genskabe private nøgler fra en ødelagt wallet.dat under opstart</translation>
</message>
<message>
+ <source>Automatically create Tor hidden service (default: %d)</source>
+ <translation>Opret automatisk skjult Tor-tjeneste (standard: %d)</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Kan ikke løse -whitebind adresse: "%s"</translation>
</message>
@@ -3388,6 +3400,14 @@
<translation>Dette er eksperimentelt software.</translation>
</message>
<message>
+ <source>Tor control port password (default: empty)</source>
+ <translation>Adgangskode for Tor kontrolport (standard: tom)</translation>
+ </message>
+ <message>
+ <source>Tor control port to use if onion listening enabled (default: %s)</source>
+ <translation>Tor kontrolport, der skal bruges, hvis onion-lytning er slået til (standard: %s)</translation>
+ </message>
+ <message>
<source>Transaction amount too small</source>
<translation>Transaktionsbeløb er for lavt</translation>
</message>
@@ -3428,6 +3448,10 @@
<translation>Advarsel</translation>
</message>
<message>
+ <source>Whether to operate in a blocks only mode (default: %u)</source>
+ <translation>Hvorvidt der skal arbejdes i kun-blokke-tilstand (standard: %u)</translation>
+ </message>
+ <message>
<source>Zapping all transactions from wallet...</source>
<translation>Zapper alle transaktioner fra tegnebog…</translation>
</message>
@@ -3513,7 +3537,7 @@
</message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
- <translation>Brug separat SOCS5-proxy for at nå andre knuder via Tor skjulte tjenester (standard: %s)</translation>
+ <translation>Brug separat SOCS5-proxy for at nå knuder via skjulte Tor-tjenester (standard: %s)</translation>
</message>
<message>
<source>(default: %s)</source>
diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts
index 42776f2c8b..6b68b3c74a 100644
--- a/src/qt/locale/bitcoin_de.ts
+++ b/src/qt/locale/bitcoin_de.ts
@@ -226,7 +226,11 @@
<source>IP/Netmask</source>
<translation>IP/Netzmaske</translation>
</message>
- </context>
+ <message>
+ <source>Banned Until</source>
+ <translation>Gesperrt bis</translation>
+ </message>
+</context>
<context>
<name>BitcoinGUI</name>
<message>
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 21df732520..0c5529955f 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -299,7 +299,7 @@
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+325"/>
+ <location filename="../bitcoingui.cpp" line="+335"/>
<source>Sign &amp;message...</source>
<translation>Sign &amp;message...</translation>
</message>
@@ -701,7 +701,7 @@
<context>
<name>ClientModel</name>
<message>
- <location filename="../clientmodel.cpp" line="+143"/>
+ <location filename="../clientmodel.cpp" line="+135"/>
<source>Network Alert</source>
<translation>Network Alert</translation>
</message>
@@ -925,7 +925,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+160"/>
+ <location line="+161"/>
<source>This label turns red if the transaction size is greater than 1000 bytes.</source>
<translation type="unfinished"></translation>
</message>
@@ -940,12 +940,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+9"/>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-32"/>
+ <location line="-33"/>
<source>yes</source>
<translation type="unfinished"></translation>
</message>
@@ -971,7 +971,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+58"/>
+ <location line="+59"/>
<location line="+60"/>
<source>(no label)</source>
<translation type="unfinished">(no label)</translation>
@@ -1086,7 +1086,7 @@
<context>
<name>HelpMessageDialog</name>
<message>
- <location filename="../utilitydialog.cpp" line="+33"/>
+ <location filename="../utilitydialog.cpp" line="+36"/>
<source>Bitcoin Core</source>
<translation type="unfinished">Bitcoin Core</translation>
</message>
@@ -1469,17 +1469,17 @@
<translation>&amp;Cancel</translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="+83"/>
+ <location filename="../optionsdialog.cpp" line="+81"/>
<source>default</source>
<translation>default</translation>
</message>
<message>
- <location line="+59"/>
+ <location line="+64"/>
<source>none</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+83"/>
+ <location line="+71"/>
<source>Confirm options reset</source>
<translation>Confirm options reset</translation>
</message>
@@ -1500,7 +1500,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+24"/>
+ <location line="+25"/>
<source>The supplied proxy address is invalid.</source>
<translation>The supplied proxy address is invalid.</translation>
</message>
@@ -1756,7 +1756,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+760"/>
+ <location line="+763"/>
<source>%1 d</source>
<translation type="unfinished"></translation>
</message>
@@ -1830,11 +1830,13 @@
<location line="+26"/>
<location line="+23"/>
<location line="+23"/>
- <location line="+36"/>
+ <location line="+23"/>
<location line="+23"/>
<location line="+36"/>
<location line="+23"/>
- <location line="+533"/>
+ <location line="+36"/>
+ <location line="+36"/>
+ <location line="+534"/>
<location line="+23"/>
<location line="+23"/>
<location line="+23"/>
@@ -1855,7 +1857,7 @@
<translation>N/A</translation>
</message>
<message>
- <location line="-1156"/>
+ <location line="-1216"/>
<source>Client version</source>
<translation>Client version</translation>
</message>
@@ -1890,12 +1892,12 @@
<translation>Startup time</translation>
</message>
<message>
- <location line="+29"/>
+ <location line="+170"/>
<source>Network</source>
<translation>Network</translation>
</message>
<message>
- <location line="+7"/>
+ <location line="-147"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
@@ -1915,12 +1917,27 @@
<translation>Current number of blocks</translation>
</message>
<message>
- <location line="+72"/>
+ <location line="+52"/>
+ <source>Memory Pool</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Current number of transactions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>Memory usage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+48"/>
<source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+231"/>
+ <location line="+233"/>
<location line="+552"/>
<source>Received</source>
<translation type="unfinished"></translation>
@@ -1943,8 +1960,8 @@
</message>
<message>
<location line="+57"/>
- <location filename="../rpcconsole.cpp" line="+281"/>
- <location line="+566"/>
+ <location filename="../rpcconsole.cpp" line="+287"/>
+ <location line="+578"/>
<source>Select a peer to view detailed information.</source>
<translation type="unfinished"></translation>
</message>
@@ -1979,8 +1996,8 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-913"/>
- <location line="+821"/>
+ <location line="-973"/>
+ <location line="+881"/>
<source>User Agent</source>
<translation type="unfinished"></translation>
</message>
@@ -2030,17 +2047,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-904"/>
+ <location line="-977"/>
<source>Last block time</source>
<translation>Last block time</translation>
</message>
<message>
- <location line="+52"/>
+ <location line="+123"/>
<source>&amp;Open</source>
<translation>&amp;Open</translation>
</message>
<message>
- <location line="+24"/>
+ <location line="+26"/>
<source>&amp;Console</source>
<translation>&amp;Console</translation>
</message>
@@ -2060,7 +2077,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../rpcconsole.cpp" line="-333"/>
+ <location filename="../rpcconsole.cpp" line="-343"/>
<source>In:</source>
<translation type="unfinished"></translation>
</message>
@@ -2070,17 +2087,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/debugwindow.ui" line="-357"/>
+ <location filename="../forms/debugwindow.ui" line="-417"/>
<source>Build date</source>
<translation>Build date</translation>
</message>
<message>
- <location line="+183"/>
+ <location line="+241"/>
<source>Debug log file</source>
<translation>Debug log file</translation>
</message>
<message>
- <location line="+83"/>
+ <location line="+85"/>
<source>Clear console</source>
<translation>Clear console</translation>
</message>
@@ -2138,7 +2155,7 @@
<translation>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</translation>
</message>
<message>
- <location line="+134"/>
+ <location line="+144"/>
<source>%1 B</source>
<translation type="unfinished"></translation>
</message>
@@ -2706,12 +2723,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+88"/>
+ <location line="+91"/>
<source>Pay only the required fee of %1</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="+22"/>
+ <location line="+23"/>
<source>Estimated to begin confirmation within %n block(s).</source>
<translation type="unfinished">
<numerusform>Estimated to begin confirmation within %n block.</numerusform>
@@ -2719,7 +2736,7 @@
</translation>
</message>
<message>
- <location line="-136"/>
+ <location line="-140"/>
<source>The recipient address is not valid. Please recheck.</source>
<translation type="unfinished"></translation>
</message>
@@ -2729,7 +2746,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+231"/>
+ <location line="+234"/>
<source>Warning: Invalid Bitcoin address</source>
<translation type="unfinished"></translation>
</message>
@@ -2744,7 +2761,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-692"/>
+ <location line="-695"/>
<source>Copy dust</source>
<translation type="unfinished"></translation>
</message>
@@ -2871,7 +2888,7 @@
<context>
<name>ShutdownWindow</name>
<message>
- <location filename="../utilitydialog.cpp" line="+81"/>
+ <location filename="../utilitydialog.cpp" line="+96"/>
<source>Bitcoin Core is shutting down...</source>
<translation type="unfinished"></translation>
</message>
@@ -3703,32 +3720,32 @@
<context>
<name>bitcoin-core</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="+260"/>
+ <location filename="../bitcoinstrings.cpp" line="+267"/>
<source>Options:</source>
<translation>Options:</translation>
</message>
<message>
- <location line="+30"/>
+ <location line="+27"/>
<source>Specify data directory</source>
<translation>Specify data directory</translation>
</message>
<message>
- <location line="-87"/>
+ <location line="-84"/>
<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="+90"/>
+ <location line="+87"/>
<source>Specify your own public address</source>
<translation>Specify your own public address</translation>
</message>
<message>
- <location line="-109"/>
+ <location line="-105"/>
<source>Accept command line and JSON-RPC commands</source>
<translation>Accept command line and JSON-RPC commands</translation>
</message>
<message>
- <location line="-113"/>
+ <location line="-118"/>
<source>If &lt;category&gt; is not supplied or if &lt;category&gt; = 1, output all debugging information.</source>
<translation type="unfinished"></translation>
</message>
@@ -3763,7 +3780,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+112"/>
+ <location line="+116"/>
<source>Error: A fatal internal error occurred, see debug.log for details</source>
<translation type="unfinished"></translation>
</message>
@@ -3783,17 +3800,17 @@
<translation>Run in the background as a daemon and accept commands</translation>
</message>
<message>
- <location line="+34"/>
+ <location line="+29"/>
<source>Unable to start HTTP server. See debug log for details.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-123"/>
+ <location line="-117"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
<message>
- <location line="-160"/>
+ <location line="-168"/>
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
<translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation>
</message>
@@ -3813,12 +3830,12 @@
<translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation>
</message>
<message>
- <location line="+57"/>
+ <location line="+60"/>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+8"/>
<source>The block database contains a block which appears to be from the future. This may be due to your computer&apos;s date and time being set incorrectly. Only rebuild the block database if you are sure that your computer&apos;s date and time are correct</source>
<translation type="unfinished"></translation>
</message>
@@ -3838,7 +3855,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+9"/>
<source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
<translation type="unfinished"></translation>
</message>
@@ -3869,11 +3886,6 @@
</message>
<message>
<location line="+11"/>
- <source>(default: 1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
<source>-maxmempool must be at least %d MB</source>
<translation type="unfinished"></translation>
</message>
@@ -3888,7 +3900,7 @@
<translation>Block creation options:</translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+6"/>
<source>Connect only to the specified node(s)</source>
<translation>Connect only to the specified node(s)</translation>
</message>
@@ -4008,22 +4020,22 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+14"/>
+ <location line="+13"/>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+2"/>
<source>Set maximum block size in bytes (default: %d)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+10"/>
<source>Specify wallet file (within data directory)</source>
<translation>Specify wallet file (within data directory)</translation>
</message>
<message>
- <location line="+18"/>
+ <location line="+16"/>
<source>Unsupported argument -benchmark ignored, use -debug=bench.</source>
<translation type="unfinished"></translation>
</message>
@@ -4078,7 +4090,7 @@
<translation>You need to rebuild the database using -reindex to change -txindex</translation>
</message>
<message>
- <location line="-304"/>
+ <location line="-306"/>
<source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
<translation type="unfinished"></translation>
</message>
@@ -4123,7 +4135,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+11"/>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4158,7 +4170,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+10"/>
<source>The transaction amount is too small to send after the fee has been deducted</source>
<translation type="unfinished"></translation>
</message>
@@ -4168,7 +4180,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+40"/>
+ <location line="+44"/>
<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>
@@ -4183,7 +4195,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+5"/>
<source>Accept public REST requests (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4213,12 +4225,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Choose data directory on startup (default: 0)</source>
- <translation type="unfinished">Choose data directory on startup (default: 0)</translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+3"/>
<source>Connect through SOCKS5 proxy</source>
<translation type="unfinished"></translation>
</message>
@@ -4328,27 +4335,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Set SSL root certificates for payment request (default: -system-)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
- <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
- <translation type="unfinished">Set language, for example &quot;de_DE&quot; (default: system locale)</translation>
- </message>
- <message>
- <location line="+4"/>
+ <location line="+6"/>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Show splash screen on startup (default: 1)</source>
- <translation type="unfinished">Show splash screen on startup (default: 1)</translation>
- </message>
- <message>
- <location line="+1"/>
<source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
<translation>Shrink debug.log file on client startup (default: 1 when no -debug)</translation>
</message>
@@ -4359,11 +4351,6 @@
</message>
<message>
<location line="+8"/>
- <source>Start minimized</source>
- <translation type="unfinished">Start minimized</translation>
- </message>
- <message>
- <location line="+1"/>
<source>The transaction amount is too small to pay the fee</source>
<translation type="unfinished"></translation>
</message>
@@ -4404,11 +4391,6 @@
</message>
<message>
<location line="+1"/>
- <source>UI Options:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation type="unfinished"></translation>
</message>
@@ -4453,27 +4435,27 @@
<translation>wallet.dat corrupt, salvage failed</translation>
</message>
<message>
- <location line="-67"/>
+ <location line="-62"/>
<source>Password for JSON-RPC connections</source>
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-198"/>
+ <location line="-205"/>
<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="+234"/>
+ <location line="+237"/>
<source>This help message</source>
<translation>This help message</translation>
</message>
<message>
- <location line="-108"/>
+ <location line="-103"/>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
<translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+59"/>
<source>Loading addresses...</source>
<translation>Loading addresses...</translation>
</message>
@@ -4483,7 +4465,7 @@
<translation>Error loading wallet.dat: Wallet corrupted</translation>
</message>
<message>
- <location line="-207"/>
+ <location line="-214"/>
<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>
@@ -4509,6 +4491,11 @@
</message>
<message>
<location line="+17"/>
+ <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4528,7 +4515,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+46"/>
+ <location line="+32"/>
+ <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
<source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source>
<translation type="unfinished"></translation>
</message>
@@ -4548,17 +4540,22 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+28"/>
+ <location line="+3"/>
+ <source>Username and hashed password for JSON-RPC connections. The field &lt;userpw&gt; comes in the format: &lt;USERNAME&gt;:&lt;SALT&gt;$&lt;HASH&gt;. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
<source>(default: %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+10"/>
<source>Always query for peer addresses via DNS lookup (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+28"/>
+ <location line="+27"/>
<source>Error loading wallet.dat</source>
<translation>Error loading wallet.dat</translation>
</message>
@@ -4628,12 +4625,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+7"/>
<source>Set key pool size to &lt;n&gt; (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+2"/>
<source>Set minimum block size in bytes (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4643,7 +4640,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+4"/>
<source>Specify configuration file (default: %s)</source>
<translation type="unfinished"></translation>
</message>
@@ -4663,17 +4660,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+4"/>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+9"/>
<source>Unknown network specified in -onlynet: &apos;%s&apos;</source>
<translation>Unknown network specified in -onlynet: &apos;%s&apos;</translation>
</message>
<message>
- <location line="-113"/>
+ <location line="-107"/>
<source>Cannot resolve -bind address: &apos;%s&apos;</source>
<translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
</message>
@@ -4683,7 +4680,7 @@
<translation>Cannot resolve -externalip address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+46"/>
+ <location line="+45"/>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
<translation>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
</message>
@@ -4698,17 +4695,17 @@
<translation>Loading block index...</translation>
</message>
<message>
- <location line="-62"/>
+ <location line="-61"/>
<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="+63"/>
+ <location line="+62"/>
<source>Loading wallet...</source>
<translation>Loading wallet...</translation>
</message>
<message>
- <location line="-56"/>
+ <location line="-55"/>
<source>Cannot downgrade wallet</source>
<translation>Cannot downgrade wallet</translation>
</message>
@@ -4718,7 +4715,7 @@
<translation>Cannot write default address</translation>
</message>
<message>
- <location line="+74"/>
+ <location line="+73"/>
<source>Rescanning...</source>
<translation>Rescanning...</translation>
</message>
diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts
index ec8261173b..8883aef989 100644
--- a/src/qt/locale/bitcoin_es.ts
+++ b/src/qt/locale/bitcoin_es.ts
@@ -2915,6 +2915,10 @@
<translation>(predeterminado: 1)</translation>
</message>
<message>
+ <source>-maxmempool must be at least %d MB</source>
+ <translation>-maxmempool debe ser por lo menos de %d MB</translation>
+ </message>
+ <message>
<source>&lt;category&gt; can be:</source>
<translation>&lt;category&gt; puede ser:</translation>
</message>
@@ -3127,6 +3131,10 @@
<translation>Intento de recuperar claves privadas de un wallet.dat corrupto</translation>
</message>
<message>
+ <source>Automatically create Tor hidden service (default: %d)</source>
+ <translation>Automáticamente crea el servicio Tor oculto (por defecto: %d)</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>No se puede resolver -whitebind address: '%s'</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts
index 140ed2445b..a80874652b 100644
--- a/src/qt/locale/bitcoin_ja.ts
+++ b/src/qt/locale/bitcoin_ja.ts
@@ -2737,6 +2737,10 @@
<translation>取引 ID をコピー</translation>
</message>
<message>
+ <source>Copy raw transaction</source>
+ <translation>生トランザクションをコピー</translation>
+ </message>
+ <message>
<source>Edit label</source>
<translation>ラベルの編集</translation>
</message>
@@ -3257,10 +3261,18 @@
<translation>最優良のチェインを有効化しています...</translation>
</message>
<message>
+ <source>Always relay transactions received from whitelisted peers (default: %d)</source>
+ <translation>ホワイトリストにあるピアから受け取ったトランザクションを常にリレーする (初期値: %d)</translation>
+ </message>
+ <message>
<source>Attempt to recover private keys from a corrupt wallet.dat on startup</source>
<translation>起動時に壊れた wallet.dat から秘密鍵を復旧することを試す</translation>
</message>
<message>
+ <source>Automatically create Tor hidden service (default: %d)</source>
+ <translation>Tor秘匿サービスを自動的に作成する (初期値: %d)</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>-whitebind アドレス '%s' を解決できません</translation>
</message>
@@ -3393,6 +3405,14 @@
<translation>これは実験的なソフトウェアです。</translation>
</message>
<message>
+ <source>Tor control port password (default: empty)</source>
+ <translation>Tor管理ポートのパスワード (初期値: 空文字)</translation>
+ </message>
+ <message>
+ <source>Tor control port to use if onion listening enabled (default: %s)</source>
+ <translation>Onion のリッスンが有効になっている場合に使用するTor管理ポート (初期値: %s)</translation>
+ </message>
+ <message>
<source>Transaction amount too small</source>
<translation>取引の額が小さ過ぎます</translation>
</message>
@@ -3433,6 +3453,10 @@
<translation>警告</translation>
</message>
<message>
+ <source>Whether to operate in a blocks only mode (default: %u)</source>
+ <translation>ブロック限定モードにおいて動作を行うかどうか (初期値: %u)</translation>
+ </message>
+ <message>
<source>Zapping all transactions from wallet...</source>
<translation>ウォレットからすべてのトランザクションを消去しています...</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts
index 8243618f11..0213c09aa7 100644
--- a/src/qt/locale/bitcoin_ko_KR.ts
+++ b/src/qt/locale/bitcoin_ko_KR.ts
@@ -3,7 +3,7 @@
<name>AddressBookPage</name>
<message>
<source>Right-click to edit address or label</source>
- <translation>지갑 주소나 이름을 수정하려면 우클릭하세요.</translation>
+ <translation>지갑 주소나 라벨을 수정하려면 우클릭하세요.</translation>
</message>
<message>
<source>Create a new address</source>
@@ -27,7 +27,7 @@
</message>
<message>
<source>&amp;Copy Address</source>
- <translation>계좌 복사(&amp;C)</translation>
+ <translation>주소 복사(&amp;C)</translation>
</message>
<message>
<source>Delete the currently selected address from the list</source>
@@ -59,11 +59,11 @@
</message>
<message>
<source>Sending addresses</source>
- <translation>보내는 주소들</translation>
+ <translation>타인 계좌 주소목록</translation>
</message>
<message>
<source>Receiving addresses</source>
- <translation>받은 주소들</translation>
+ <translation>내 계좌 주소목록</translation>
</message>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
@@ -75,7 +75,7 @@
</message>
<message>
<source>Copy &amp;Label</source>
- <translation>표 복사</translation>
+ <translation>라벨 복사</translation>
</message>
<message>
<source>&amp;Edit</source>
@@ -87,7 +87,7 @@
</message>
<message>
<source>Comma separated file (*.csv)</source>
- <translation>각각의 파일에 쉼표하기(*.csv)</translation>
+ <translation>쉼표로 구분된 파일(*.csv)</translation>
</message>
<message>
<source>Exporting Failed</source>
@@ -95,14 +95,14 @@
</message>
<message>
<source>There was an error trying to save the address list to %1. Please try again.</source>
- <translation>%1으로 주소 리스트를 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요.</translation>
+ <translation>%1으로 주소 목록을 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요.</translation>
</message>
</context>
<context>
<name>AddressTableModel</name>
<message>
<source>Label</source>
- <translation>표</translation>
+ <translation>라벨</translation>
</message>
<message>
<source>Address</source>
@@ -110,7 +110,7 @@
</message>
<message>
<source>(no label)</source>
- <translation>(표 없음)</translation>
+ <translation>(라벨 없음)</translation>
</message>
</context>
<context>
@@ -129,7 +129,7 @@
</message>
<message>
<source>Repeat new passphrase</source>
- <translation>새 암호 반복</translation>
+ <translation>새로운 암호 재확인</translation>
</message>
<message>
<source>Encrypt wallet</source>
@@ -141,7 +141,7 @@
</message>
<message>
<source>Unlock wallet</source>
- <translation>지갑 열기</translation>
+ <translation>지갑 잠금해제</translation>
</message>
<message>
<source>This operation needs your wallet passphrase to decrypt the wallet.</source>
@@ -157,11 +157,11 @@
</message>
<message>
<source>Confirm wallet encryption</source>
- <translation>지갑의 암호화를 확정</translation>
+ <translation>지갑 암호화 승인</translation>
</message>
<message>
<source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
- <translation>경고: 만약 암호화된 지갑의 비밀번호를 잃어버릴 경우, 모든 비트코인들을 잃어버릴 수 있습니다!</translation>
+ <translation>경고: 만약 암호화 된 지갑의 비밀번호를 잃어버릴 경우, &lt;b&gt;모든 비트코인들을 잃어버릴 수 있습니다&lt;/b&gt;!</translation>
</message>
<message>
<source>Are you sure you wish to encrypt your wallet?</source>
@@ -169,17 +169,21 @@
</message>
<message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
- <translation>중요: 본인 지갑파일에서 만든 예전 백업들은 새로 생성한 암화화된 지갑 파일로 교체됩니다. 보안상 이유로 이전에 암호화 하지 않은 지갑 파일 백업은 사용할 수 없게 되니 빠른 시일 내로 새로 암화화된 지갑을 사용하시기 바랍니다.</translation>
+ <translation>중요: 본인 지갑파일에서 만든 예전 백업들은 새로 생성한 암호화 된 지갑 파일로 교체됩니다. 보안상 이유로 이전에 암호화 하지 않은 지갑 파일 백업은 사용할 수 없게 되니 빠른 시일 내로 새로 암호화 된 지갑을 사용하시기 바랍니다.</translation>
</message>
<message>
<source>Warning: The Caps Lock key is on!</source>
- <translation>경고: 캡스록 키가 켜져있습니다!</translation>
+ <translation>경고: Caps Lock키가 켜져있습니다!</translation>
</message>
<message>
<source>Wallet encrypted</source>
<translation>지갑 암호화 완료</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>지갑의 기존 암호와 새로운 암호를 입력해주세요.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>지갑 암호화 실패</translation>
</message>
@@ -964,6 +968,18 @@
<translation>프록시의 포트번호입니다(예: 9050)</translation>
</message>
<message>
+ <source>IPv4</source>
+ <translation>IPv4</translation>
+ </message>
+ <message>
+ <source>IPv6</source>
+ <translation>IPv6</translation>
+ </message>
+ <message>
+ <source>Tor</source>
+ <translation>Tor</translation>
+ </message>
+ <message>
<source>&amp;Window</source>
<translation>창(&amp;W)</translation>
</message>
@@ -1071,6 +1087,10 @@
<translation>아직 사용 가능하지 않은 채굴된 잔액</translation>
</message>
<message>
+ <source>Balances</source>
+ <translation>잔액</translation>
+ </message>
+ <message>
<source>Total:</source>
<translation>총액:</translation>
</message>
@@ -1082,6 +1102,10 @@
<source>Your current balance in watch-only addresses</source>
<translation>모니터링 지갑의 현재 잔액</translation>
</message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>최근 거래</translation>
+ </message>
</context>
<context>
<name>PaymentServer</name>
@@ -1152,10 +1176,18 @@
<translation>비트코인 주소를 입력하기 (예. %1)</translation>
</message>
<message>
+ <source>%1 s</source>
+ <translation>%1 초</translation>
+ </message>
+ <message>
<source>N/A</source>
<translation>없음</translation>
</message>
- </context>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
<context>
<name>QRImageWidget</name>
<message>
@@ -1203,7 +1235,11 @@
</message>
<message>
<source>Using OpenSSL version</source>
- <translation>오픈SSL 버전을 사용합니다</translation>
+ <translation>사용중인 OpenSSL 버전</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>사용중인 BerkeleyDB 버전</translation>
</message>
<message>
<source>Startup time</source>
@@ -1230,6 +1266,22 @@
<translation>현재 블럭 수</translation>
</message>
<message>
+ <source>Received</source>
+ <translation>받음</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>보냄</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;피어</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>버전</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>최종 블럭 시각</translation>
</message>
@@ -1290,7 +1342,7 @@
</message>
<message>
<source>&amp;Label:</source>
- <translation>표:</translation>
+ <translation>라벨:</translation>
</message>
<message>
<source>&amp;Message:</source>
@@ -1432,7 +1484,7 @@
</message>
<message>
<source>(no label)</source>
- <translation>(표 없음)</translation>
+ <translation>(라벨 없음)</translation>
</message>
<message>
<source>(no message)</source>
@@ -1498,6 +1550,14 @@
<translation>주소변경</translation>
</message>
<message>
+ <source>Transaction Fee:</source>
+ <translation>거래 수수료:</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>권장:</translation>
+ </message>
+ <message>
<source>Send to multiple recipients at once</source>
<translation>다수의 수령인들에게 한번에 보내기</translation>
</message>
diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts
index 6cded5e135..c36e1af1d8 100644
--- a/src/qt/locale/bitcoin_nb.ts
+++ b/src/qt/locale/bitcoin_nb.ts
@@ -2737,6 +2737,10 @@
<translation>Kopier transaksjons-ID</translation>
</message>
<message>
+ <source>Copy raw transaction</source>
+ <translation>Kopier råtransaksjon</translation>
+ </message>
+ <message>
<source>Edit label</source>
<translation>Rediger merkelapp</translation>
</message>
@@ -3041,11 +3045,11 @@
</message>
<message>
<source>Enable publish raw block in &lt;address&gt;</source>
- <translation>Slå på publish raw block i &lt;address&gt;</translation>
+ <translation>Slå på publisering av råblokk i &lt;address&gt;</translation>
</message>
<message>
<source>Enable publish raw transaction in &lt;address&gt;</source>
- <translation>Slå på publish raw transaction i &lt;address&gt;</translation>
+ <translation>Slå på publisering av råtransaksjon i &lt;address&gt;</translation>
</message>
<message>
<source>Error initializing block database</source>
@@ -3252,10 +3256,18 @@
<translation>Aktiverer beste kjede...</translation>
</message>
<message>
+ <source>Always relay transactions received from whitelisted peers (default: %d)</source>
+ <translation>Alltid videresend transaksjoner mottatt fra hvitlistede noder (standardverdi: %d)</translation>
+ </message>
+ <message>
<source>Attempt to recover private keys from a corrupt wallet.dat on startup</source>
<translation>Forsøk å berge private nøkler fra en korrupt wallet.dat ved oppstart</translation>
</message>
<message>
+ <source>Automatically create Tor hidden service (default: %d)</source>
+ <translation>Automatisk opprette Tor skjult tjeneste (standardverdi: %d)</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Kan ikke løse -whitebind-adresse: '%s'</translation>
</message>
@@ -3388,6 +3400,14 @@
<translation>Dette er eksperimentell programvare.</translation>
</message>
<message>
+ <source>Tor control port password (default: empty)</source>
+ <translation>Passord for Tor-kontrollport (standardverdi: tom)</translation>
+ </message>
+ <message>
+ <source>Tor control port to use if onion listening enabled (default: %s)</source>
+ <translation>Tor-kontrollport å bruke hvis onion-lytting er aktivert (standardverdi: %s)</translation>
+ </message>
+ <message>
<source>Transaction amount too small</source>
<translation>Transaksjonen er for liten</translation>
</message>
@@ -3428,6 +3448,10 @@
<translation>Advarsel</translation>
</message>
<message>
+ <source>Whether to operate in a blocks only mode (default: %u)</source>
+ <translation>Hvorvidt å operere i modus med kun blokker (standardverdi: %u)</translation>
+ </message>
+ <message>
<source>Zapping all transactions from wallet...</source>
<translation>Zapper alle transaksjoner fra lommeboken...</translation>
</message>
diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts
index 228e02a5ee..52196f0372 100644
--- a/src/qt/locale/bitcoin_pl.ts
+++ b/src/qt/locale/bitcoin_pl.ts
@@ -222,7 +222,15 @@
</context>
<context>
<name>BanTableModel</name>
- </context>
+ <message>
+ <source>IP/Netmask</source>
+ <translation>IP/Maska Sieci</translation>
+ </message>
+ <message>
+ <source>Banned Until</source>
+ <translation>Blokada do</translation>
+ </message>
+</context>
<context>
<name>BitcoinGUI</name>
<message>
@@ -1068,6 +1076,18 @@
<translation>Port proxy (np. 9050)</translation>
</message>
<message>
+ <source>IPv4</source>
+ <translation>IPv4</translation>
+ </message>
+ <message>
+ <source>IPv6</source>
+ <translation>IPv6</translation>
+ </message>
+ <message>
+ <source>Tor</source>
+ <translation>Tor</translation>
+ </message>
+ <message>
<source>&amp;Window</source>
<translation>&amp;Okno</translation>
</message>
@@ -1454,6 +1474,10 @@
<translation>&amp;Węzły</translation>
</message>
<message>
+ <source>Banned peers</source>
+ <translation>Blokowane węzły</translation>
+ </message>
+ <message>
<source>Select a peer to view detailed information.</source>
<translation>Wybierz węzeł żeby zobaczyć szczegóły.</translation>
</message>
@@ -1542,6 +1566,14 @@
<translation>Wyczyść konsolę</translation>
</message>
<message>
+ <source>Ban Node for</source>
+ <translation>Blokuj węzeł na okres</translation>
+ </message>
+ <message>
+ <source>&amp;Unban Node</source>
+ <translation>Odblokuj węzeł</translation>
+ </message>
+ <message>
<source>Welcome to the Bitcoin Core RPC console.</source>
<translation>Witaj w konsoli Bitcoin Core RPC.</translation>
</message>
@@ -1586,6 +1618,14 @@
<translation>Wyjściowy</translation>
</message>
<message>
+ <source>Yes</source>
+ <translation>Tak</translation>
+ </message>
+ <message>
+ <source>No</source>
+ <translation>Nie</translation>
+ </message>
+ <message>
<source>Unknown</source>
<translation>Nieznany</translation>
</message>
@@ -1981,6 +2021,10 @@
<source>Payment request expired.</source>
<translation>Żądanie płatności upłynęło.</translation>
</message>
+ <message>
+ <source>Pay only the required fee of %1</source>
+ <translation>Zapłać tylko wymaganą opłatę %1</translation>
+ </message>
<message numerus="yes">
<source>Estimated to begin confirmation within %n block(s).</source>
<translation><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform></translation>
diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts
index 4863591ac4..e57c051aa1 100644
--- a/src/qt/locale/bitcoin_pt_BR.ts
+++ b/src/qt/locale/bitcoin_pt_BR.ts
@@ -1550,6 +1550,14 @@
<translation>A duração de um ping excepcional no momento.</translation>
</message>
<message>
+ <source>Ping Wait</source>
+ <translation>Espera de ping</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Offset de tempo</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Horário do último bloco</translation>
</message>
@@ -2638,6 +2646,10 @@
<translation>Mostrar ou não endereços Bitcoin na lista de transações.</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intenção/Propósito definido pelo usuário para a transação</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Quantidade debitada ou creditada ao saldo.</translation>
</message>
@@ -2717,6 +2729,10 @@
<translation>Copiar ID da transação</translation>
</message>
<message>
+ <source>Copy raw transaction</source>
+ <translation>Copia os dados brutos da transação</translation>
+ </message>
+ <message>
<source>Edit label</source>
<translation>Editar rótulo</translation>
</message>
@@ -2868,6 +2884,18 @@
<translation>Se &lt;category&gt; não for suprida ou se &lt;category&gt; = 1, mostrar toda informação de depuração.</translation>
</message>
<message>
+ <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Por favor verifique se a data e horário estão corretos no seu computador! Se o seu relógio estiver incorreto, a Carteira Bitcoin não irá funcionar corretamente.</translation>
+ </message>
+ <message>
+ <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source>
+ <translation>Corte: a ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar ( -reindex , faça o download de toda a blockchain novamente)</translation>
+ </message>
+ <message>
+ <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source>
+ <translation>Rescans não são possíveis no modo de corte. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente.</translation>
+ </message>
+ <message>
<source>Error: A fatal internal error occurred, see debug.log for details</source>
<translation>Erro: Um erro interno fatal ocorreu, veja debug.log para detalhes</translation>
</message>
@@ -2992,6 +3020,22 @@
<translation>Você quer reconstruir o banco de dados de blocos agora?</translation>
</message>
<message>
+ <source>Enable publish hash block in &lt;address&gt;</source>
+ <translation>Abilitar a publicação da hash do block em &lt;endereço&gt;</translation>
+ </message>
+ <message>
+ <source>Enable publish hash transaction in &lt;address&gt;</source>
+ <translation>Abilitar a publicação da hash da transação em &lt;endereço&gt;</translation>
+ </message>
+ <message>
+ <source>Enable publish raw block in &lt;address&gt;</source>
+ <translation>Abilitar a publicação dos dados brutos do block em &lt;endereço&gt;</translation>
+ </message>
+ <message>
+ <source>Enable publish raw transaction in &lt;address&gt;</source>
+ <translation>Abilitar a publicação dos dados brutos da transação em &lt;endereço&gt;</translation>
+ </message>
+ <message>
<source>Error initializing block database</source>
<translation>Erro ao inicializar banco de dados de blocos</translation>
</message>
@@ -3112,6 +3156,10 @@
<translation>Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6</translation>
</message>
<message>
+ <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>Conecte ao endereço dado para receber conecções JSON-RPC. Use a notação [destino]:porta para IPv6. Essa opção pode ser especificada várias vezes (padrão: conecte a todas as interfaces)</translation>
+ </message>
+ <message>
<source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
<translation>Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado.</translation>
</message>
@@ -3144,6 +3192,10 @@
<translation>A quantia da transação é muito pequena para mandar </translation>
</message>
<message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit&lt;https://www.openssl.org/&gt; e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. </translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
<translation>Você precisa reconstruir o banco de dados usando -reindex para sair do modo prune. Isso irá rebaixar todo o blockchain.</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts
index b69a3bda54..ad0a7b3b50 100644
--- a/src/qt/locale/bitcoin_ru.ts
+++ b/src/qt/locale/bitcoin_ru.ts
@@ -218,7 +218,15 @@
</context>
<context>
<name>BanTableModel</name>
- </context>
+ <message>
+ <source>IP/Netmask</source>
+ <translation>IP/префикс</translation>
+ </message>
+ <message>
+ <source>Banned Until</source>
+ <translation>Заблокировано до</translation>
+ </message>
+</context>
<context>
<name>BitcoinGUI</name>
<message>
@@ -421,6 +429,10 @@
<source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
<translation>Показать помощь по Bitcoin Core и получить список доступных параметров командной строки.</translation>
</message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n активных соединений с сетью Bitcoin</numerusform><numerusform>%n активных соединений с сетью Bitcoin</numerusform><numerusform>%n активных соединений с сетью Bitcoin</numerusform><numerusform>%n активных соединений с сетью Bitcoin</numerusform></translation>
+ </message>
<message>
<source>No block source available...</source>
<translation>Источник блоков недоступен...</translation>
@@ -433,10 +445,22 @@
<source>%n hour(s)</source>
<translation><numerusform>%n час</numerusform><numerusform>%n часа</numerusform><numerusform>%n часов</numerusform><numerusform>%n часов</numerusform></translation>
</message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n день</numerusform><numerusform>%n дня</numerusform><numerusform>%n дней</numerusform><numerusform>%n дней</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n неделю</numerusform><numerusform>%n недели</numerusform><numerusform>%n недель</numerusform><numerusform>%n недель</numerusform></translation>
+ </message>
<message>
<source>%1 and %2</source>
<translation>%1 и %2</translation>
</message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n год</numerusform><numerusform>%n лет</numerusform><numerusform>%n лет</numerusform><numerusform>%n года</numerusform></translation>
+ </message>
<message>
<source>%1 behind</source>
<translation>%1 позади</translation>
@@ -893,7 +917,15 @@
<source>Error</source>
<translation>Ошибка</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n ГБ свободного места доступно</numerusform><numerusform>%n ГБ свободного места доступно</numerusform><numerusform>%n ГБ свободного места доступно</numerusform><numerusform>%n ГБ свободного места доступно</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(из необходимых %n ГБ)</numerusform><numerusform>(из необходимых %n ГБ)</numerusform><numerusform>(из необходимых %n ГБ)</numerusform><numerusform>(из необходимых %n ГБ)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
@@ -1044,10 +1076,34 @@
<translation>Порт прокси-сервера (например, 9050)</translation>
</message>
<message>
+ <source>Used for reaching peers via:</source>
+ <translation>Используется для достижения участников через:</translation>
+ </message>
+ <message>
+ <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source>
+ <translation>Показывается, если включено прокси SOCKS5 по умолчанию, используемое для соединения с участниками по этому типу сети.</translation>
+ </message>
+ <message>
+ <source>IPv4</source>
+ <translation>IPv4</translation>
+ </message>
+ <message>
+ <source>IPv6</source>
+ <translation>IPv6</translation>
+ </message>
+ <message>
<source>Tor</source>
<translation>Tor</translation>
</message>
<message>
+ <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source>
+ <translation>Подключаться к сети Bitcoin через прокси SOCKS5 для скрытых сервисов Tor.</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source>
+ <translation>Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor:</translation>
+ </message>
+ <message>
<source>&amp;Window</source>
<translation>&amp;Окно</translation>
</message>
@@ -1434,10 +1490,18 @@
<translation>&amp;Участники</translation>
</message>
<message>
+ <source>Banned peers</source>
+ <translation>Заблокированные участники</translation>
+ </message>
+ <message>
<source>Select a peer to view detailed information.</source>
<translation>Выберите участника для просмотра подробностей.</translation>
</message>
<message>
+ <source>Whitelisted</source>
+ <translation>Доверенный</translation>
+ </message>
+ <message>
<source>Direction</source>
<translation>Направление</translation>
</message>
@@ -1446,6 +1510,18 @@
<translation>Версия</translation>
</message>
<message>
+ <source>Starting Block</source>
+ <translation>Начальный блок</translation>
+ </message>
+ <message>
+ <source>Synced Headers</source>
+ <translation>Синхронизировано заголовков</translation>
+ </message>
+ <message>
+ <source>Synced Blocks</source>
+ <translation>Синхронизировано блоков</translation>
+ </message>
+ <message>
<source>User Agent</source>
<translation>Юзер-агент</translation>
</message>
@@ -1474,6 +1550,14 @@
<translation>Время задержки</translation>
</message>
<message>
+ <source>The duration of a currently outstanding ping.</source>
+ <translation>Длительность текущего пинга.</translation>
+ </message>
+ <message>
+ <source>Ping Wait</source>
+ <translation>Время задержки</translation>
+ </message>
+ <message>
<source>Time Offset</source>
<translation>Смещение времени</translation>
</message>
@@ -1522,6 +1606,34 @@
<translation>Очистить консоль</translation>
</message>
<message>
+ <source>&amp;Disconnect Node</source>
+ <translation>&amp;Отключить узел</translation>
+ </message>
+ <message>
+ <source>Ban Node for</source>
+ <translation>Заблокировать узел на</translation>
+ </message>
+ <message>
+ <source>1 &amp;hour</source>
+ <translation>1 &amp;час</translation>
+ </message>
+ <message>
+ <source>1 &amp;day</source>
+ <translation>1 &amp;день</translation>
+ </message>
+ <message>
+ <source>1 &amp;week</source>
+ <translation>1 &amp;неделю</translation>
+ </message>
+ <message>
+ <source>1 &amp;year</source>
+ <translation>1 &amp;год</translation>
+ </message>
+ <message>
+ <source>&amp;Unban Node</source>
+ <translation>&amp;Разблокировать узел</translation>
+ </message>
+ <message>
<source>Welcome to the Bitcoin Core RPC console.</source>
<translation>Добро пожаловать в RPC-консоль Bitcoin Core.</translation>
</message>
@@ -1550,6 +1662,10 @@
<translation>%1 ГБ</translation>
</message>
<message>
+ <source>(node id: %1)</source>
+ <translation>(номер узла: %1)</translation>
+ </message>
+ <message>
<source>via %1</source>
<translation>через %1</translation>
</message>
@@ -1942,6 +2058,10 @@
<translation>Копировать размен</translation>
</message>
<message>
+ <source>Total Amount %1</source>
+ <translation>Общая сумма %1</translation>
+ </message>
+ <message>
<source>or</source>
<translation>или</translation>
</message>
@@ -2287,6 +2407,10 @@
<source>Status</source>
<translation>Статус</translation>
</message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, разослано через %n узел</numerusform><numerusform>, разослано через %n узла</numerusform><numerusform>, разослано через %n узлов</numerusform><numerusform>, разослано через %n узлов</numerusform></translation>
+ </message>
<message>
<source>Date</source>
<translation>Дата</translation>
@@ -2323,6 +2447,10 @@
<source>Credit</source>
<translation>Кредит</translation>
</message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>будет доступно через %n блок</numerusform><numerusform>будет доступно через %n блока</numerusform><numerusform>будет доступно через %n блоков</numerusform><numerusform>будет доступно через %n блоков</numerusform></translation>
+ </message>
<message>
<source>not accepted</source>
<translation>не принято</translation>
@@ -2395,6 +2523,10 @@
<source>, has not been successfully broadcast yet</source>
<translation>, ещё не было успешно разослано</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Открыто для ещё %n блока</numerusform><numerusform>Открыто для ещё %n блоков</numerusform><numerusform>Открыто для ещё %n блоков</numerusform><numerusform>Открыто для ещё %n блоков</numerusform></translation>
+ </message>
<message>
<source>unknown</source>
<translation>неизвестно</translation>
@@ -2425,6 +2557,10 @@
<source>Immature (%1 confirmations, will be available after %2)</source>
<translation>Незрелый (%1 подтверждений, будет доступен после %2)</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Открыто для ещё %n блока</numerusform><numerusform>Открыто для ещё %n блоков</numerusform><numerusform>Открыто для ещё %n блоков</numerusform><numerusform>Открыто для ещё %n блоков</numerusform></translation>
+ </message>
<message>
<source>Open until %1</source>
<translation>Открыто до %1</translation>
@@ -2585,6 +2721,10 @@
<translation>Скопировать ID транзакции</translation>
</message>
<message>
+ <source>Copy raw transaction</source>
+ <translation>Скопировать исходную транзакции</translation>
+ </message>
+ <message>
<source>Edit label</source>
<translation>Изменить метку</translation>
</message>
@@ -2732,10 +2872,42 @@
<translation>Принимать командную строку и команды JSON-RPC</translation>
</message>
<message>
+ <source>If &lt;category&gt; is not supplied or if &lt;category&gt; = 1, output all debugging information.</source>
+ <translation>Если &lt;category&gt; не предоставлена или равна 1, выводить всю отладочную информацию.</translation>
+ </message>
+ <message>
+ <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Максимальная сумма комиссий (%s) для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Внимание: убедитесь, что дата и время на Вашем компьютере выставлены верно! Если Ваши часы идут неправильно, Bitcoin Core будет работать некорректно.</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source>
+ <translation>Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение.</translation>
+ </message>
+ <message>
+ <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source>
+ <translation>Удаление: последняя синхронизация кошелька вышла за рамки удаленных данных. Вам нужен -reindex (скачать всю цепь блоков в случае удаленного узла)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим несовместим с -txindex и -rescan. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, &gt;%u = целевой размер в Мб для файлов блоков)</translation>
+ </message>
+ <message>
+ <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source>
+ <translation>Повторное сканирование не возможно в режиме удаления. Вам надо будет использовать -reindex, который загрузит заново всю цепь блоков.</translation>
+ </message>
+ <message>
<source>Error: A fatal internal error occurred, see debug.log for details</source>
<translation>Ошибка: произошла неустранимая ошибка, подробности в debug.log</translation>
</message>
<message>
+ <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source>
+ <translation>Комиссия (в %s/Кб) для добавления к вашим транзакциям (по умолчанию: %s)</translation>
+ </message>
+ <message>
<source>Pruning blockstore...</source>
<translation>Очистка хранилища блоков...</translation>
</message>
@@ -2744,6 +2916,10 @@
<translation>Запускаться в фоне как демон и принимать команды</translation>
</message>
<message>
+ <source>Unable to start HTTP server. See debug log for details.</source>
+ <translation>Невозможно запустить HTTP сервер. Смотри debug лог для подробностей.</translation>
+ </message>
+ <message>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Принимать подключения извне (по умолчанию: 1, если не используется -proxy или -connect)</translation>
</message>
@@ -2768,6 +2944,10 @@
<translation>Задать число потоков проверки скрипта (от %u до %d, 0=авто, &lt;0 = оставить столько ядер свободными, по умолчанию: %d)</translation>
</message>
<message>
+ <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source>
+ <translation>База данных блоков содержит блок, который появляется из будущего. Это может из-за некорректно установленных даты и времени на вашем компьютере. Остается только перестроивать базу блоков, если вы уверены, что дата и время корректны.</translation>
+ </message>
+ <message>
<source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
<translation>Это пре-релизная тестовая сборка - используйте на свой страх и риск - не используйте для добычи или торговых приложений</translation>
</message>
@@ -2776,6 +2956,10 @@
<translation>Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен.</translation>
</message>
<message>
+ <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source>
+ <translation>Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание и нет -proxy)</translation>
+ </message>
+ <message>
<source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
<translation>ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d)</translation>
</message>
@@ -2804,6 +2988,10 @@
<translation>(по умолчанию: 1)</translation>
</message>
<message>
+ <source>-maxmempool must be at least %d MB</source>
+ <translation>-maxmempool должен быть как минимум %d MB</translation>
+ </message>
+ <message>
<source>&lt;category&gt; can be:</source>
<translation>&lt;category&gt; может быть:</translation>
</message>
@@ -2836,6 +3024,22 @@
<translation>Пересобрать БД блоков прямо сейчас?</translation>
</message>
<message>
+ <source>Enable publish hash block in &lt;address&gt;</source>
+ <translation>Включить публичный хеш блока в &lt;address&gt;</translation>
+ </message>
+ <message>
+ <source>Enable publish hash transaction in &lt;address&gt;</source>
+ <translation>Включить публичный хеш транзакции в &lt;address&gt;</translation>
+ </message>
+ <message>
+ <source>Enable publish raw block in &lt;address&gt;</source>
+ <translation>Включить публичный сырой блок в &lt;address&gt;</translation>
+ </message>
+ <message>
+ <source>Enable publish raw transaction in &lt;address&gt;</source>
+ <translation>Включить публичную сырую транзакцию в &lt;address&gt;</translation>
+ </message>
+ <message>
<source>Error initializing block database</source>
<translation>Ошибка инициализации БД блоков</translation>
</message>
@@ -2872,6 +3076,10 @@
<translation>Неверный -onion адрес: '%s'</translation>
</message>
<message>
+ <source>Keep the transaction memory pool below &lt;n&gt; megabytes (default: %u)</source>
+ <translation>Сбрасывать транзакции из памяти на диск каждые &lt;n&gt; мегабайт (по умолчанию: %u)</translation>
+ </message>
+ <message>
<source>Not enough file descriptors available.</source>
<translation>Недостаточно файловых дескрипторов.</translation>
</message>
@@ -2900,10 +3108,26 @@
<translation>Укажите файл бумажника (внутри каталога данных)</translation>
</message>
<message>
+ <source>Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Неподдерживаемый аргумент -benchmark проигнорирован, используйте -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Неподдерживаемый аргумент -debugnet проигнорирован, используйте -debug=net.</translation>
+ </message>
+ <message>
+ <source>Unsupported argument -tor found, use -onion.</source>
+ <translation>Обнаружен не поддерживаемый параметр -tor, используйте -onion.</translation>
+ </message>
+ <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Использовать UPnP для проброса порта (по умолчанию: %u)</translation>
</message>
<message>
+ <source>User Agent comment (%s) contains unsafe characters.</source>
+ <translation>Комментарий пользователя (%s) содержит небезопасные символы.</translation>
+ </message>
+ <message>
<source>Verifying blocks...</source>
<translation>Проверка блоков...</translation>
</message>
@@ -2960,6 +3184,10 @@
<translation>Выполнить команду, когда приходит соответствующее сообщение о тревоге или наблюдается очень длинное расщепление цепи (%s в команде заменяется на сообщение)</translation>
</message>
<message>
+ <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source>
+ <translation>Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми для создания, ретрансляции, получения транзакции (по умолчанию: %s)</translation>
+ </message>
+ <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u)</translation>
</message>
@@ -3016,6 +3244,18 @@
<translation>Активируется лучшая цепь...</translation>
</message>
<message>
+ <source>Always relay transactions received from whitelisted peers (default: %d)</source>
+ <translation>Всегда транслировать транзакции, полученные из белого списка участников (по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source>
+ <translation>Попытаться восстановить приватные ключи из повреждённого wallet.dat при запуске</translation>
+ </message>
+ <message>
+ <source>Automatically create Tor hidden service (default: %d)</source>
+ <translation>Автоматически создавать скрытый Tor сервис (по умолчанию: %d)</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation>
</message>
@@ -3040,6 +3280,10 @@
<translation>Ошибка чтения базы данных, работа завершается.</translation>
</message>
<message>
+ <source>Imports blocks from external blk000??.dat file on startup</source>
+ <translation>Импортировать блоки из внешнего файла blk000?.dat при запуске</translation>
+ </message>
+ <message>
<source>Information</source>
<translation>Информация</translation>
</message>
@@ -3092,6 +3336,14 @@
<translation>Получать и отображать P2P сетевые тревоги (по умолчанию: %u)</translation>
</message>
<message>
+ <source>Reducing -maxconnections from %d to %d, because of system limitations.</source>
+ <translation>Уменьшите -maxconnections с %d до %d, из-за ограничений системы.</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions on startup</source>
+ <translation>Перепроверить цепь блоков на предмет отсутствующих в бумажнике транзакций при запуске</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Выводить информацию трассировки/отладки на консоль вместо файла debug.log</translation>
</message>
@@ -3136,6 +3388,14 @@
<translation>Это экспериментальное ПО.</translation>
</message>
<message>
+ <source>Tor control port password (default: empty)</source>
+ <translation>Пароль контроля порта Tor (по умолчанию: пустой)</translation>
+ </message>
+ <message>
+ <source>Tor control port to use if onion listening enabled (default: %s)</source>
+ <translation>Порт контроля Tor используется, если включено прослушивание onion (по умолчанию: %s)</translation>
+ </message>
+ <message>
<source>Transaction amount too small</source>
<translation>Сумма транзакции слишком мала</translation>
</message>
@@ -3160,6 +3420,10 @@
<translation>Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s)</translation>
</message>
<message>
+ <source>Upgrade wallet to latest format on startup</source>
+ <translation>Обновить бумажник до последнего формата при запуске</translation>
+ </message>
+ <message>
<source>Username for JSON-RPC connections</source>
<translation>Имя для подключений JSON-RPC</translation>
</message>
@@ -3172,10 +3436,18 @@
<translation>Внимание</translation>
</message>
<message>
+ <source>Whether to operate in a blocks only mode (default: %u)</source>
+ <translation>Будет работать в режиме только блоков (по умолчанию: %u)</translation>
+ </message>
+ <message>
<source>Zapping all transactions from wallet...</source>
<translation>Стираем все транзакции из кошелька...</translation>
</message>
<message>
+ <source>ZeroMQ notification options:</source>
+ <translation>ZeroMQ параметры оповещения:</translation>
+ </message>
+ <message>
<source>wallet.dat corrupt, salvage failed</source>
<translation>wallet.dat повреждён, спасение данных не удалось</translation>
</message>
@@ -3208,6 +3480,22 @@
<translation>(1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные)</translation>
</message>
<message>
+ <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Установлено очень большое значение -maxtxfee. Такие большие комиссии могут быть уплачены в отдельной транзакции.</translation>
+ </message>
+ <message>
+ <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Установлено очень большое значение -paytxfee. Такие большие комиссии могут быть уплачены в отдельной транзакции.</translation>
+ </message>
+ <message>
+ <source>Do not keep transactions in the mempool longer than &lt;n&gt; hours (default: %u)</source>
+ <translation>Не хранить транзакции в памяти дольше, чем &lt;n&gt; часов (по умолчанию %u)</translation>
+ </message>
+ <message>
+ <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Ошибка чтения wallet.dat! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными.</translation>
+ </message>
+ <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u)</translation>
</message>
@@ -3224,6 +3512,18 @@
<translation>Выводить отладочную информацию (по умолчанию: %u, указание &lt;category&gt; необязательно)</translation>
</message>
<message>
+ <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source>
+ <translation>Текущая длина строки версии сети (%i) превышает максимальную длину (%i). Увеливается количество или размер uacomments.</translation>
+ </message>
+ <message>
+ <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source>
+ <translation>Пытается ограничить исходящий трафик до (в МБ за 24ч), 0 = не ограничивать (по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Обнаружен не поддерживаемый аргумент -socks. Выбор версии SOCKS более невозможен, поддерживаются только прокси SOCKS5.</translation>
+ </message>
+ <message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation>Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts
index 69c175645b..bb7fcf7075 100644
--- a/src/qt/locale/bitcoin_sv.ts
+++ b/src/qt/locale/bitcoin_sv.ts
@@ -2055,6 +2055,10 @@ Var vänlig och försök igen.</translation>
<translation>Kopiera växel</translation>
</message>
<message>
+ <source>Total Amount %1</source>
+ <translation>Total summa %1</translation>
+ </message>
+ <message>
<source>or</source>
<translation>eller</translation>
</message>
@@ -2086,6 +2090,10 @@ Var vänlig och försök igen.</translation>
<source>Payment request expired.</source>
<translation>Betalningsbegäran löpte ut.</translation>
</message>
+ <message>
+ <source>Pay only the required fee of %1</source>
+ <translation>Betala endast den nödvändiga avgiften på %1</translation>
+ </message>
<message numerus="yes">
<source>Estimated to begin confirmation within %n block(s).</source>
<translation><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform></translation>
@@ -2718,6 +2726,10 @@ Var vänlig och försök igen.</translation>
<translation>Kopiera transaktions ID</translation>
</message>
<message>
+ <source>Copy raw transaction</source>
+ <translation>Kopiera rå transaktion</translation>
+ </message>
+ <message>
<source>Edit label</source>
<translation>Ändra etikett</translation>
</message>
@@ -3177,6 +3189,10 @@ Var vänlig och försök igen.</translation>
<translation>Exekvera kommando när ett relevant meddelande är mottagen eller när vi ser en väldigt lång förgrening (%s i cmd är utbytt med ett meddelande)</translation>
</message>
<message>
+ <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source>
+ <translation>Avgifter (i %s/kB) mindre än detta betraktas som nollavgift för vidarebefordran, mining och transaktionsskapande (förvalt: %s)</translation>
+ </message>
+ <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen börjar att konfirmeras inom n blocks (förvalt: %u)</translation>
</message>
@@ -3229,6 +3245,18 @@ Var vänlig och försök igen.</translation>
<translation>Aktiverar bästa kedjan...</translation>
</message>
<message>
+ <source>Always relay transactions received from whitelisted peers (default: %d)</source>
+ <translation>Vidarebefordra alltid transaktioner från vitlistade noder (förval: %d)</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source>
+ <translation>Försök att rädda privata nycklar från en korrupt wallet.dat vid uppstart</translation>
+ </message>
+ <message>
+ <source>Automatically create Tor hidden service (default: %d)</source>
+ <translation>Skapa automatiskt dold tjänst i Tor (förval: %d)</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Kan inte matcha -whitebind adress: '%s'</translation>
</message>
@@ -3253,6 +3281,10 @@ Var vänlig och försök igen.</translation>
<translation>Fel vid läsning från databas, avslutar.</translation>
</message>
<message>
+ <source>Imports blocks from external blk000??.dat file on startup</source>
+ <translation>Importera block från extern blk000??.dat-fil vid uppstart</translation>
+ </message>
+ <message>
<source>Information</source>
<translation>Information</translation>
</message>
@@ -3309,6 +3341,10 @@ Var vänlig och försök igen.</translation>
<translation>Minskar -maxconnections från %d till %d, på grund av systembegränsningar.</translation>
</message>
<message>
+ <source>Rescan the block chain for missing wallet transactions on startup</source>
+ <translation>Sök i blockkedjan efter saknade plånbokstransaktioner vid uppstart</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Skicka trace-/debuginformation till terminalen istället för till debug.log</translation>
</message>
@@ -3353,6 +3389,14 @@ Var vänlig och försök igen.</translation>
<translation>Detta är experimentmjukvara.</translation>
</message>
<message>
+ <source>Tor control port password (default: empty)</source>
+ <translation>Lösenord för Tor-kontrollport (förval: inget)</translation>
+ </message>
+ <message>
+ <source>Tor control port to use if onion listening enabled (default: %s)</source>
+ <translation>Tor-kontrollport att använda om onion är aktiverat (förval: %s)</translation>
+ </message>
+ <message>
<source>Transaction amount too small</source>
<translation>Transaktions belopp för liten</translation>
</message>
@@ -3377,6 +3421,10 @@ Var vänlig och försök igen.</translation>
<translation>Det går inte att binda till %s på den här datorn (bind returnerade felmeddelande %s)</translation>
</message>
<message>
+ <source>Upgrade wallet to latest format on startup</source>
+ <translation>Uppgradera plånbok till senaste formatet vid uppstart</translation>
+ </message>
+ <message>
<source>Username for JSON-RPC connections</source>
<translation>Användarnamn för JSON-RPC-anslutningar</translation>
</message>
@@ -3389,6 +3437,10 @@ Var vänlig och försök igen.</translation>
<translation>Varning</translation>
</message>
<message>
+ <source>Whether to operate in a blocks only mode (default: %u)</source>
+ <translation>Ska allt göras i endast block-läge (förval: %u)</translation>
+ </message>
+ <message>
<source>Zapping all transactions from wallet...</source>
<translation>Töm plånboken på alla transaktioner...</translation>
</message>
diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts
index b4dbf85a33..adf9071ede 100644
--- a/src/qt/locale/bitcoin_zh_TW.ts
+++ b/src/qt/locale/bitcoin_zh_TW.ts
@@ -403,7 +403,7 @@
</message>
<message>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
- <translation>要求付款(產生 QR Code 和位元幣付款協議的 URI)</translation>
+ <translation>要求付款(產生 QR Code 和位元幣付款協議的資源識別碼: URI)</translation>
</message>
<message>
<source>&amp;About Bitcoin Core</source>
@@ -423,7 +423,7 @@
</message>
<message>
<source>Open a bitcoin: URI or payment request</source>
- <translation>開啓 bitcoin 協議的 URI 或付款要求</translation>
+ <translation>開啓 bitcoin 協議的資源識別碼(URI)或付款要求</translation>
</message>
<message>
<source>&amp;Command-line options</source>
@@ -907,7 +907,7 @@
</message>
<message>
<source>Use a custom data directory:</source>
- <translation>使用自定的資料目錄:</translation>
+ <translation>使用自訂的資料目錄:</translation>
</message>
<message>
<source>Bitcoin Core</source>
@@ -997,7 +997,7 @@
</message>
<message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
- <translation>在交易頁籤的情境選單出現的第三方(比如說區塊探索網站)網址連結。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。</translation>
+ <translation>在交易頁籤的情境選單出現的第三方網址連結(URL),比如說區塊探索網站。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。</translation>
</message>
<message>
<source>Third party transaction URLs</source>
@@ -1291,11 +1291,11 @@
</message>
<message>
<source>Payment request fetch URL is invalid: %1</source>
- <translation>取得付款要求的 URL 無效: %1</translation>
+ <translation>取得付款要求的網址連結(URL)無效: %1</translation>
</message>
<message>
<source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
- <translation>沒辦法解析 URI 位址!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。</translation>
+ <translation>沒辦法解析資源識別碼(URI)!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。</translation>
</message>
<message>
<source>Payment request file handling</source>
@@ -1923,7 +1923,7 @@
</message>
<message>
<source>Custom change address</source>
- <translation>自定找零位址</translation>
+ <translation>自訂找零位址</translation>
</message>
<message>
<source>Transaction Fee:</source>
@@ -2194,11 +2194,11 @@
</message>
<message>
<source>This is an unauthenticated payment request.</source>
- <translation>這是個沒驗證過的付款要求。</translation>
+ <translation>這是個沒有驗證過身份的付款要求。</translation>
</message>
<message>
<source>This is an authenticated payment request.</source>
- <translation>這是個已驗證的付款要求。</translation>
+ <translation>這是個已經驗證過身份的付款要求。</translation>
</message>
<message>
<source>Enter a label for this address to add it to the list of used addresses</source>
@@ -2206,7 +2206,7 @@
</message>
<message>
<source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
- <translation>附加在位元幣付款協議 URI 中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。</translation>
+ <translation>附加在位元幣付款協議的資源識別碼(URI)中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。</translation>
</message>
<message>
<source>Pay To:</source>
@@ -2733,6 +2733,10 @@
<translation>複製交易識別碼</translation>
</message>
<message>
+ <source>Copy raw transaction</source>
+ <translation>複製交易原始資料</translation>
+ </message>
+ <message>
<source>Edit label</source>
<translation>編輯標記</translation>
</message>
@@ -3094,7 +3098,7 @@
</message>
<message>
<source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
- <translation>只有連接到網絡節點 &lt;net&gt; (IPv4,IPv6或onion)</translation>
+ <translation>只和 &lt;net&gt; 網路上的節點連線(ipv4, ipv6, 或 onion)</translation>
</message>
<message>
<source>Prune cannot be configured with a negative value.</source>
@@ -3249,10 +3253,18 @@
<translation>啟用最佳鏈結...</translation>
</message>
<message>
+ <source>Always relay transactions received from whitelisted peers (default: %d)</source>
+ <translation>無條件轉發從白名點節點收到的交易(預設值: %d)</translation>
+ </message>
+ <message>
<source>Attempt to recover private keys from a corrupt wallet.dat on startup</source>
<translation>啟動時嘗試從壞掉的錢包檔 wallet.dat 復原密鑰</translation>
</message>
<message>
+ <source>Automatically create Tor hidden service (default: %d)</source>
+ <translation>自動產生 Tor 隱藏服務(預設值: %d)</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation>
</message>
@@ -3385,6 +3397,14 @@
<translation>這套軟體屬於實驗性質。</translation>
</message>
<message>
+ <source>Tor control port password (default: empty)</source>
+ <translation>Tor 控制埠密碼(預設值: 空白)</translation>
+ </message>
+ <message>
+ <source>Tor control port to use if onion listening enabled (default: %s)</source>
+ <translation>開啟聽候 onion 連線時的 Tor 控制埠號碼(預設值: %s)</translation>
+ </message>
+ <message>
<source>Transaction amount too small</source>
<translation>交易金額太小</translation>
</message>
@@ -3425,6 +3445,10 @@
<translation>警告</translation>
</message>
<message>
+ <source>Whether to operate in a blocks only mode (default: %u)</source>
+ <translation>是否要用只要區塊模式運作(預設值: %u)</translation>
+ </message>
+ <message>
<source>Zapping all transactions from wallet...</source>
<translation>正在砍掉錢包中的所有交易...</translation>
</message>
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
index 1f54c62b6e..1000c143f3 100644
--- a/src/qt/paymentrequestplus.cpp
+++ b/src/qt/paymentrequestplus.cpp
@@ -201,7 +201,7 @@ QList<std::pair<CScript,CAmount> > PaymentRequestPlus::getPayTo() const
const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data();
CScript s(scriptStr, scriptStr+details.outputs(i).script().size());
- result.append(make_pair(s, details.outputs(i).amount()));
+ result.append(std::make_pair(s, details.outputs(i).amount()));
}
return result;
}
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 0fd86da034..ec4e598bf9 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -585,7 +585,7 @@ void SendCoinsDialog::updateFeeSectionControls()
ui->checkBoxMinimumFee ->setEnabled(ui->radioCustomFee->isChecked());
ui->labelMinFeeWarning ->setEnabled(ui->radioCustomFee->isChecked());
ui->radioCustomPerKilobyte ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
- ui->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
+ ui->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked() && CoinControlDialog::coinControl->HasSelected());
ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
}
@@ -600,7 +600,10 @@ void SendCoinsDialog::updateGlobalFeeVariables()
{
nTxConfirmTarget = defaultConfirmTarget;
payTxFee = CFeeRate(ui->customFee->value());
- fPayAtLeastCustomFee = ui->radioCustomAtLeast->isChecked();
+
+ // if user has selected to set a minimum absolute fee, pass the value to coincontrol
+ // set nMinimumTotalFee to 0 in case of user has selected that the fee is per KB
+ CoinControlDialog::coinControl->nMinimumTotalFee = ui->radioCustomAtLeast->isChecked() ? ui->customFee->value() : 0;
}
fSendFreeTransactions = ui->checkBoxFreeTx->isChecked();
@@ -707,8 +710,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
if (!checked && model) // coin control features disabled
CoinControlDialog::coinControl->SetNull();
- if (checked)
- coinControlUpdateLabels();
+ coinControlUpdateLabels();
}
// Coin Control: button inputs -> show actual coin control dialog
@@ -782,9 +784,24 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
// Coin Control: update labels
void SendCoinsDialog::coinControlUpdateLabels()
{
- if (!model || !model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures())
+ if (!model || !model->getOptionsModel())
return;
+ if (model->getOptionsModel()->getCoinControlFeatures())
+ {
+ // enable minium absolute fee UI controls
+ ui->radioCustomAtLeast->setVisible(true);
+
+ // only enable the feature if inputs are selected
+ ui->radioCustomAtLeast->setEnabled(CoinControlDialog::coinControl->HasSelected());
+ }
+ else
+ {
+ // in case coin control is disabled (=default), hide minimum absolute fee UI controls
+ ui->radioCustomAtLeast->setVisible(false);
+ return;
+ }
+
// set pay amounts
CoinControlDialog::payAmounts.clear();
CoinControlDialog::fSubtractFeeFromAmount = false;
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 3bda459245..1f2d77aef0 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -62,6 +62,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
{
entry.push_back(Pair("txid", tx.GetHash().GetHex()));
+ entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)));
entry.push_back(Pair("version", tx.nVersion));
entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
UniValue vin(UniValue::VARR);
@@ -133,6 +134,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp)
"{\n"
" \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
" \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
+ " \"size\" : n, (numeric) The transaction size\n"
" \"version\" : n, (numeric) The version\n"
" \"locktime\" : ttt, (numeric) The lock time\n"
" \"vin\" : [ (array of json objects)\n"
@@ -429,6 +431,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp)
"\nResult:\n"
"{\n"
" \"txid\" : \"id\", (string) The transaction id\n"
+ " \"size\" : n, (numeric) The transaction size\n"
" \"version\" : n, (numeric) The version\n"
" \"locktime\" : ttt, (numeric) The lock time\n"
" \"vin\" : [ (array of json objects)\n"
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 8dcab832cb..57e0edc4b4 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1023,7 +1023,7 @@ public:
// Serialize the script
if (nInput != nIn)
// Blank out other inputs' signatures
- ::Serialize(s, CScript(), nType, nVersion);
+ ::Serialize(s, CScriptBase(), nType, nVersion);
else
SerializeScriptCode(s, nType, nVersion);
// Serialize the nSequence
diff --git a/src/script/script.cpp b/src/script/script.cpp
index 263c89defe..9c77ed9fc1 100644
--- a/src/script/script.cpp
+++ b/src/script/script.cpp
@@ -205,9 +205,9 @@ bool CScript::IsPayToScriptHash() const
{
// Extra-fast test for pay-to-script-hash CScripts:
return (this->size() == 23 &&
- this->at(0) == OP_HASH160 &&
- this->at(1) == 0x14 &&
- this->at(22) == OP_EQUAL);
+ (*this)[0] == OP_HASH160 &&
+ (*this)[1] == 0x14 &&
+ (*this)[22] == OP_EQUAL);
}
bool CScript::IsPushOnly(const_iterator pc) const
diff --git a/src/script/script.h b/src/script/script.h
index a38d33a189..3650957fc9 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -7,6 +7,7 @@
#define BITCOIN_SCRIPT_SCRIPT_H
#include "crypto/common.h"
+#include "prevector.h"
#include <assert.h>
#include <climits>
@@ -354,8 +355,10 @@ private:
int64_t m_value;
};
+typedef prevector<28, unsigned char> CScriptBase;
+
/** Serialized script, used inside transaction inputs and outputs */
-class CScript : public std::vector<unsigned char>
+class CScript : public CScriptBase
{
protected:
CScript& push_int64(int64_t n)
@@ -376,9 +379,10 @@ protected:
}
public:
CScript() { }
- CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { }
- CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { }
- CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { }
+ CScript(const CScript& b) : CScriptBase(b.begin(), b.end()) { }
+ CScript(const_iterator pbegin, const_iterator pend) : CScriptBase(pbegin, pend) { }
+ CScript(std::vector<unsigned char>::const_iterator pbegin, std::vector<unsigned char>::const_iterator pend) : CScriptBase(pbegin, pend) { }
+ CScript(const unsigned char* pbegin, const unsigned char* pend) : CScriptBase(pbegin, pend) { }
CScript& operator+=(const CScript& b)
{
@@ -611,7 +615,7 @@ public:
void clear()
{
// The default std::vector::clear() does not release memory.
- std::vector<unsigned char>().swap(*this);
+ CScriptBase().swap(*this);
}
};
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 8b43183b6d..90f557fc60 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -16,7 +16,7 @@
using namespace std;
-typedef vector<unsigned char> valtype;
+typedef std::vector<unsigned char> valtype;
TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {}
@@ -118,7 +118,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
bool fSolved =
SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH;
// Append serialized subscript whether or not it is completely signed:
- scriptSig << static_cast<valtype>(subscript);
+ scriptSig << valtype(subscript.begin(), subscript.end());
if (!fSolved) return false;
}
diff --git a/src/serialize.h b/src/serialize.h
index 53d8af142f..5fe7fc1f35 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -20,7 +20,7 @@
#include <utility>
#include <vector>
-class CScript;
+#include "prevector.h"
static const unsigned int MAX_SIZE = 0x02000000;
@@ -49,26 +49,26 @@ inline T* NCONST_PTR(const T* val)
* @note These functions avoid the undefined case of indexing into an empty
* vector, as well as that of indexing after the end of the vector.
*/
-template <class T, class TAl>
-inline T* begin_ptr(std::vector<T,TAl>& v)
+template <typename V>
+inline typename V::value_type* begin_ptr(V& v)
{
return v.empty() ? NULL : &v[0];
}
/** Get begin pointer of vector (const version) */
-template <class T, class TAl>
-inline const T* begin_ptr(const std::vector<T,TAl>& v)
+template <typename V>
+inline const typename V::value_type* begin_ptr(const V& v)
{
return v.empty() ? NULL : &v[0];
}
/** Get end pointer of vector (non-const version) */
-template <class T, class TAl>
-inline T* end_ptr(std::vector<T,TAl>& v)
+template <typename V>
+inline typename V::value_type* end_ptr(V& v)
{
return v.empty() ? NULL : (&v[0] + v.size());
}
/** Get end pointer of vector (const version) */
-template <class T, class TAl>
-inline const T* end_ptr(const std::vector<T,TAl>& v)
+template <typename V>
+inline const typename V::value_type* end_ptr(const V& v)
{
return v.empty() ? NULL : (&v[0] + v.size());
}
@@ -391,6 +391,12 @@ public:
pbegin = (char*)begin_ptr(v);
pend = (char*)end_ptr(v);
}
+ template <unsigned int N, typename T, typename S, typename D>
+ explicit CFlatData(prevector<N, T, S, D> &v)
+ {
+ pbegin = (char*)begin_ptr(v);
+ pend = (char*)end_ptr(v);
+ }
char* begin() { return pbegin; }
const char* begin() const { return pbegin; }
char* end() { return pend; }
@@ -486,6 +492,20 @@ template<typename Stream, typename C> void Serialize(Stream& os, const std::basi
template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
/**
+ * prevector
+ * prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
+ */
+template<unsigned int N, typename T> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
+template<unsigned int N, typename T, typename V> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&);
+template<unsigned int N, typename T> inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion);
+template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
+template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&);
+template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion);
+template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
+template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&);
+template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion);
+
+/**
* vector
* vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
*/
@@ -500,13 +520,6 @@ template<typename Stream, typename T, typename A, typename V> void Unserialize_i
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
/**
- * others derived from vector
- */
-extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion);
-template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
-template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
-
-/**
* pair
*/
template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
@@ -588,6 +601,96 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
/**
+ * prevector
+ */
+template<unsigned int N, typename T>
+unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
+{
+ return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
+}
+
+template<unsigned int N, typename T, typename V>
+unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&)
+{
+ unsigned int nSize = GetSizeOfCompactSize(v.size());
+ for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
+ nSize += GetSerializeSize((*vi), nType, nVersion);
+ return nSize;
+}
+
+template<unsigned int N, typename T>
+inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion)
+{
+ return GetSerializeSize_impl(v, nType, nVersion, T());
+}
+
+
+template<typename Stream, unsigned int N, typename T>
+void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
+{
+ WriteCompactSize(os, v.size());
+ if (!v.empty())
+ os.write((char*)&v[0], v.size() * sizeof(T));
+}
+
+template<typename Stream, unsigned int N, typename T, typename V>
+void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&)
+{
+ WriteCompactSize(os, v.size());
+ for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
+ ::Serialize(os, (*vi), nType, nVersion);
+}
+
+template<typename Stream, unsigned int N, typename T>
+inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion)
+{
+ Serialize_impl(os, v, nType, nVersion, T());
+}
+
+
+template<typename Stream, unsigned int N, typename T>
+void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
+{
+ // Limit size per read so bogus size value won't cause out of memory
+ v.clear();
+ unsigned int nSize = ReadCompactSize(is);
+ unsigned int i = 0;
+ while (i < nSize)
+ {
+ unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
+ v.resize(i + blk);
+ is.read((char*)&v[i], blk * sizeof(T));
+ i += blk;
+ }
+}
+
+template<typename Stream, unsigned int N, typename T, typename V>
+void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&)
+{
+ v.clear();
+ unsigned int nSize = ReadCompactSize(is);
+ unsigned int i = 0;
+ unsigned int nMid = 0;
+ while (nMid < nSize)
+ {
+ nMid += 5000000 / sizeof(T);
+ if (nMid > nSize)
+ nMid = nSize;
+ v.resize(nMid);
+ for (; i < nMid; i++)
+ Unserialize(is, v[i], nType, nVersion);
+ }
+}
+
+template<typename Stream, unsigned int N, typename T>
+inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion)
+{
+ Unserialize_impl(is, v, nType, nVersion, T());
+}
+
+
+
+/**
* vector
*/
template<typename T, typename A>
@@ -678,28 +781,6 @@ inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersio
/**
- * others derived from vector
- */
-inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
-{
- return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
-}
-
-template<typename Stream>
-void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
-{
- Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
-}
-
-template<typename Stream>
-void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
-{
- Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
-}
-
-
-
-/**
* pair
*/
template<typename K, typename T>
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 1d7c9f65c0..531cd59d5a 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -119,7 +119,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
{
tx.vout[0].nValue -= 1000000;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
@@ -139,7 +140,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
{
tx.vout[0].nValue -= 10000000;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
@@ -158,7 +160,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
tx.vout[0].nValue = 4900000000LL;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
tx.vin[0].prevout.hash = hash;
tx.vin.resize(2);
tx.vin[1].scriptSig = CScript() << OP_1;
@@ -166,7 +168,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[1].prevout.n = 0;
tx.vout[0].nValue = 5900000000LL;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
delete pblocktemplate;
mempool.clear();
@@ -177,7 +179,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].scriptSig = CScript() << OP_0 << OP_1;
tx.vout[0].nValue = 0;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
delete pblocktemplate;
mempool.clear();
@@ -190,12 +192,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
script = CScript() << OP_0;
tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script));
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
tx.vin[0].prevout.hash = hash;
- tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script;
+ tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end());
tx.vout[0].nValue -= 1000000;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
delete pblocktemplate;
mempool.clear();
@@ -206,10 +208,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = 4900000000LL;
tx.vout[0].scriptPubKey = CScript() << OP_1;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
tx.vout[0].scriptPubKey = CScript() << OP_2;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
delete pblocktemplate;
mempool.clear();
@@ -235,7 +237,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].scriptPubKey = CScript() << OP_1;
tx.nLockTime = chainActive.Tip()->nHeight+1;
hash = tx.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST));
// time locked
@@ -249,7 +251,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx2.vout[0].scriptPubKey = CScript() << OP_1;
tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1;
hash = tx2.GetHash();
- mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx2));
+ mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx2));
BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST));
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp
new file mode 100644
index 0000000000..01a45b540d
--- /dev/null
+++ b/src/test/prevector_tests.cpp
@@ -0,0 +1,217 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <vector>
+#include "prevector.h"
+#include "random.h"
+
+#include "serialize.h"
+#include "streams.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(PrevectorTests, TestingSetup)
+
+template<unsigned int N, typename T>
+class prevector_tester {
+ typedef std::vector<T> realtype;
+ realtype real_vector;
+
+ typedef prevector<N, T> pretype;
+ pretype pre_vector;
+
+ typedef typename pretype::size_type Size;
+
+ void test() {
+ const pretype& const_pre_vector = pre_vector;
+ BOOST_CHECK_EQUAL(real_vector.size(), pre_vector.size());
+ BOOST_CHECK_EQUAL(real_vector.empty(), pre_vector.empty());
+ for (Size s = 0; s < real_vector.size(); s++) {
+ BOOST_CHECK(real_vector[s] == pre_vector[s]);
+ BOOST_CHECK(&(pre_vector[s]) == &(pre_vector.begin()[s]));
+ BOOST_CHECK(&(pre_vector[s]) == &*(pre_vector.begin() + s));
+ BOOST_CHECK(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size()));
+ }
+ // BOOST_CHECK(realtype(pre_vector) == real_vector);
+ BOOST_CHECK(pretype(real_vector.begin(), real_vector.end()) == pre_vector);
+ BOOST_CHECK(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector);
+ size_t pos = 0;
+ BOOST_FOREACH(const T& v, pre_vector) {
+ BOOST_CHECK(v == real_vector[pos++]);
+ }
+ BOOST_REVERSE_FOREACH(const T& v, pre_vector) {
+ BOOST_CHECK(v == real_vector[--pos]);
+ }
+ BOOST_FOREACH(const T& v, const_pre_vector) {
+ BOOST_CHECK(v == real_vector[pos++]);
+ }
+ BOOST_REVERSE_FOREACH(const T& v, const_pre_vector) {
+ BOOST_CHECK(v == real_vector[--pos]);
+ }
+ CDataStream ss1(SER_DISK, 0);
+ CDataStream ss2(SER_DISK, 0);
+ ss1 << real_vector;
+ ss2 << pre_vector;
+ BOOST_CHECK_EQUAL(ss1.size(), ss2.size());
+ for (Size s = 0; s < ss1.size(); s++) {
+ BOOST_CHECK_EQUAL(ss1[s], ss2[s]);
+ }
+ }
+
+public:
+ void resize(Size s) {
+ real_vector.resize(s);
+ BOOST_CHECK_EQUAL(real_vector.size(), s);
+ pre_vector.resize(s);
+ BOOST_CHECK_EQUAL(pre_vector.size(), s);
+ test();
+ }
+
+ void reserve(Size s) {
+ real_vector.reserve(s);
+ BOOST_CHECK(real_vector.capacity() >= s);
+ pre_vector.reserve(s);
+ BOOST_CHECK(pre_vector.capacity() >= s);
+ test();
+ }
+
+ void insert(Size position, const T& value) {
+ real_vector.insert(real_vector.begin() + position, value);
+ pre_vector.insert(pre_vector.begin() + position, value);
+ test();
+ }
+
+ void insert(Size position, Size count, const T& value) {
+ real_vector.insert(real_vector.begin() + position, count, value);
+ pre_vector.insert(pre_vector.begin() + position, count, value);
+ test();
+ }
+
+ template<typename I>
+ void insert_range(Size position, I first, I last) {
+ real_vector.insert(real_vector.begin() + position, first, last);
+ pre_vector.insert(pre_vector.begin() + position, first, last);
+ test();
+ }
+
+ void erase(Size position) {
+ real_vector.erase(real_vector.begin() + position);
+ pre_vector.erase(pre_vector.begin() + position);
+ test();
+ }
+
+ void erase(Size first, Size last) {
+ real_vector.erase(real_vector.begin() + first, real_vector.begin() + last);
+ pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last);
+ test();
+ }
+
+ void update(Size pos, const T& value) {
+ real_vector[pos] = value;
+ pre_vector[pos] = value;
+ test();
+ }
+
+ void push_back(const T& value) {
+ real_vector.push_back(value);
+ pre_vector.push_back(value);
+ test();
+ }
+
+ void pop_back() {
+ real_vector.pop_back();
+ pre_vector.pop_back();
+ test();
+ }
+
+ void clear() {
+ real_vector.clear();
+ pre_vector.clear();
+ }
+
+ void assign(Size n, const T& value) {
+ real_vector.assign(n, value);
+ pre_vector.assign(n, value);
+ }
+
+ Size size() {
+ return real_vector.size();
+ }
+
+ Size capacity() {
+ return pre_vector.capacity();
+ }
+
+ void shrink_to_fit() {
+ pre_vector.shrink_to_fit();
+ test();
+ }
+};
+
+BOOST_AUTO_TEST_CASE(PrevectorTestInt)
+{
+ for (int j = 0; j < 64; j++) {
+ prevector_tester<8, int> test;
+ for (int i = 0; i < 2048; i++) {
+ int r = insecure_rand();
+ if ((r % 4) == 0) {
+ test.insert(insecure_rand() % (test.size() + 1), insecure_rand());
+ }
+ if (test.size() > 0 && ((r >> 2) % 4) == 1) {
+ test.erase(insecure_rand() % test.size());
+ }
+ if (((r >> 4) % 8) == 2) {
+ int new_size = std::max<int>(0, std::min<int>(30, test.size() + (insecure_rand() % 5) - 2));
+ test.resize(new_size);
+ }
+ if (((r >> 7) % 8) == 3) {
+ test.insert(insecure_rand() % (test.size() + 1), 1 + (insecure_rand() % 2), insecure_rand());
+ }
+ if (((r >> 10) % 8) == 4) {
+ int del = std::min<int>(test.size(), 1 + (insecure_rand() % 2));
+ int beg = insecure_rand() % (test.size() + 1 - del);
+ test.erase(beg, beg + del);
+ }
+ if (((r >> 13) % 16) == 5) {
+ test.push_back(insecure_rand());
+ }
+ if (test.size() > 0 && ((r >> 17) % 16) == 6) {
+ test.pop_back();
+ }
+ if (((r >> 21) % 32) == 7) {
+ int values[4];
+ int num = 1 + (insecure_rand() % 4);
+ for (int i = 0; i < num; i++) {
+ values[i] = insecure_rand();
+ }
+ test.insert_range(insecure_rand() % (test.size() + 1), values, values + num);
+ }
+ if (((r >> 26) % 32) == 8) {
+ int del = std::min<int>(test.size(), 1 + (insecure_rand() % 4));
+ int beg = insecure_rand() % (test.size() + 1 - del);
+ test.erase(beg, beg + del);
+ }
+ r = insecure_rand();
+ if (r % 32 == 9) {
+ test.reserve(insecure_rand() % 32);
+ }
+ if ((r >> 5) % 64 == 10) {
+ test.shrink_to_fit();
+ }
+ if (test.size() > 0) {
+ test.update(insecure_rand() % test.size(), insecure_rand());
+ }
+ if (((r >> 11) & 1024) == 11) {
+ test.clear();
+ }
+ if (((r >> 21) & 512) == 12) {
+ test.assign(insecure_rand() % 32, insecure_rand());
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 2a486f08e4..ce22975005 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -72,6 +72,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), runtime_error);
string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000";
BOOST_CHECK_NO_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx));
+ BOOST_CHECK_EQUAL(find_value(r.get_obj(), "size").get_int(), 193);
BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").get_int(), 1);
BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").get_int(), 0);
BOOST_CHECK_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx+" extra"), runtime_error);
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index 16c9a4a868..e36aca8dfa 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -25,7 +25,7 @@ using namespace std;
static std::vector<unsigned char>
Serialize(const CScript& s)
{
- std::vector<unsigned char> sSerialized(s);
+ std::vector<unsigned char> sSerialized(s.begin(), s.end());
return sSerialized;
}
@@ -339,8 +339,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
// SignSignature doesn't know how to sign these. We're
// not testing validating signatures, so just create
// dummy signatures that DO include the correct P2SH scripts:
- txTo.vin[3].scriptSig << OP_11 << OP_11 << static_cast<vector<unsigned char> >(oneAndTwo);
- txTo.vin[4].scriptSig << static_cast<vector<unsigned char> >(fifteenSigops);
+ txTo.vin[3].scriptSig << OP_11 << OP_11 << vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
+ txTo.vin[4].scriptSig << vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());
BOOST_CHECK(::AreInputsStandard(txTo, coins));
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
@@ -362,7 +362,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd1.vin.resize(1);
txToNonStd1.vin[0].prevout.n = 5;
txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
- txToNonStd1.vin[0].scriptSig << static_cast<vector<unsigned char> >(sixteenSigops);
+ txToNonStd1.vin[0].scriptSig << vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());
BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins));
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U);
@@ -374,7 +374,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd2.vin.resize(1);
txToNonStd2.vin[0].prevout.n = 6;
txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
- txToNonStd2.vin[0].scriptSig << static_cast<vector<unsigned char> >(twentySigops);
+ txToNonStd2.vin[0].scriptSig << vector<unsigned char>(twentySigops.begin(), twentySigops.end());
BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins));
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U);
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 882f9eb199..0059e4a998 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -260,7 +260,7 @@ public:
TestBuilder& PushRedeem()
{
- DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey));
+ DoPush(std::vector<unsigned char>(scriptPubKey.begin(), scriptPubKey.end()));
return *this;
}
@@ -892,7 +892,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig);
// dummy scriptSigCopy with placeholder, should always choose non-placeholder:
- scriptSigCopy = CScript() << OP_0 << static_cast<vector<unsigned char> >(pkSingle);
+ scriptSigCopy = CScript() << OP_0 << vector<unsigned char>(pkSingle.begin(), pkSingle.end());
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
BOOST_CHECK(combined == scriptSig);
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy);
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index b26fed99f2..ea2b9b795f 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -20,7 +20,7 @@ using namespace std;
static std::vector<unsigned char>
Serialize(const CScript& s)
{
- std::vector<unsigned char> sSerialized(s);
+ std::vector<unsigned char> sSerialized(s.begin(), s.end());
return sSerialized;
}
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index 351870014d..9645c7c942 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -150,7 +150,7 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPo
CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
- hasNoDependencies, inChainValue);
+ hasNoDependencies, inChainValue, spendsCoinbase);
}
void Shutdown(void* parg)
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
index 815b227411..343c27673c 100644
--- a/src/test/test_bitcoin.h
+++ b/src/test/test_bitcoin.h
@@ -65,10 +65,11 @@ struct TestMemPoolEntryHelper
double dPriority;
unsigned int nHeight;
bool hadNoDependencies;
+ bool spendsCoinbase;
TestMemPoolEntryHelper() :
nFee(0), nTime(0), dPriority(0.0), nHeight(1),
- hadNoDependencies(false) { }
+ hadNoDependencies(false), spendsCoinbase(false) { }
CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL);
@@ -78,5 +79,6 @@ struct TestMemPoolEntryHelper
TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; }
TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; }
TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; }
+ TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; }
};
#endif
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 6d1df0b3d1..9d25139481 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -11,6 +11,7 @@
#include "main.h"
#include "policy/fees.h"
#include "streams.h"
+#include "timedata.h"
#include "util.h"
#include "utilmoneystr.h"
#include "utiltime.h"
@@ -20,9 +21,11 @@ using namespace std;
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
- bool poolHasNoInputsOf, CAmount _inChainInputValue):
+ bool poolHasNoInputsOf, CAmount _inChainInputValue,
+ bool _spendsCoinbase):
tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
- hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue)
+ hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue),
+ spendsCoinbase(_spendsCoinbase)
{
nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
nModSize = tx.CalculateModifiedSize(nTxSize);
@@ -478,22 +481,26 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
}
}
-void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight)
+void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags)
{
- // Remove transactions spending a coinbase which are now immature
+ // Remove transactions spending a coinbase which are now immature and no-longer-final transactions
LOCK(cs);
list<CTransaction> transactionsToRemove;
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
const CTransaction& tx = it->GetTx();
- BOOST_FOREACH(const CTxIn& txin, tx.vin) {
- indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
- if (it2 != mapTx.end())
- continue;
- const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
- if (nCheckFrequency != 0) assert(coins);
- if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
- transactionsToRemove.push_back(tx);
- break;
+ if (!CheckFinalTx(tx, flags)) {
+ transactionsToRemove.push_back(tx);
+ } else if (it->GetSpendsCoinbase()) {
+ BOOST_FOREACH(const CTxIn& txin, tx.vin) {
+ indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
+ if (it2 != mapTx.end())
+ continue;
+ const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
+ if (nCheckFrequency != 0) assert(coins);
+ if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
+ transactionsToRemove.push_back(tx);
+ break;
+ }
}
}
}
diff --git a/src/txmempool.h b/src/txmempool.h
index c470bbe28f..c4ea51557c 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -67,6 +67,7 @@ private:
unsigned int entryHeight; //! Chain height when entering the mempool
bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool
CAmount inChainInputValue; //! Sum of all txin values that are already in blockchain
+ bool spendsCoinbase; //! keep track of transactions that spend a coinbase
// Information about descendants of this transaction that are in the
// mempool; if we remove this transaction we must remove all of these
@@ -80,7 +81,7 @@ private:
public:
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
- bool poolHasNoInputsOf, CAmount _inChainInputValue);
+ bool poolHasNoInputsOf, CAmount _inChainInputValue, bool spendsCoinbase);
CTxMemPoolEntry(const CTxMemPoolEntry& other);
const CTransaction& GetTx() const { return this->tx; }
@@ -109,6 +110,8 @@ public:
uint64_t GetCountWithDescendants() const { return nCountWithDescendants; }
uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; }
+
+ bool GetSpendsCoinbase() const { return spendsCoinbase; }
};
// Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index.
@@ -376,7 +379,7 @@ public:
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true);
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
- void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight);
+ void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index b6eaca80b3..db60e498dd 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -65,6 +65,8 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
entry.push_back(Pair("blockindex", wtx.nIndex));
entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
+ } else {
+ entry.push_back(Pair("trusted", wtx.IsTrusted()));
}
uint256 hash = wtx.GetHash();
entry.push_back(Pair("txid", hash.GetHex()));
@@ -1421,7 +1423,9 @@ UniValue listtransactions(const UniValue& params, bool fHelp)
" \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
" 'send' category of transactions.\n"
" \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
- " 'receive' category of transactions.\n"
+ " 'receive' category of transactions. Negative confirmations indicate the\n"
+ " transation conflicts with the block chain\n"
+ " \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
" \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
" category of transactions.\n"
" \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n"
@@ -2174,7 +2178,7 @@ UniValue settxfee(const UniValue& params, bool fHelp)
if (fHelp || params.size() < 1 || params.size() > 1)
throw runtime_error(
"settxfee amount\n"
- "\nSet the transaction fee per kB.\n"
+ "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
"\nArguments:\n"
"1. amount (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n"
"\nResult\n"
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index b062226dd9..30b9869be0 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -41,7 +41,6 @@ CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS;
-bool fPayAtLeastCustomFee = false;
/**
* Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
@@ -608,6 +607,14 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
wtx.BindWallet(this);
wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0)));
AddToSpends(hash);
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin) {
+ if (mapWallet.count(txin.prevout.hash)) {
+ CWalletTx& prevtx = mapWallet[txin.prevout.hash];
+ if (prevtx.nIndex == -1 && !prevtx.hashBlock.IsNull()) {
+ MarkConflicted(prevtx.hashBlock, wtx.GetHash());
+ }
+ }
+ }
}
else
{
@@ -727,6 +734,20 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
{
{
AssertLockHeld(cs_wallet);
+
+ if (pblock) {
+ BOOST_FOREACH(const CTxIn& txin, tx.vin) {
+ std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout);
+ while (range.first != range.second) {
+ if (range.first->second != tx.GetHash()) {
+ LogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), pblock->GetHash().ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
+ MarkConflicted(pblock->GetHash(), range.first->second);
+ }
+ range.first++;
+ }
+ }
+ }
+
bool fExisted = mapWallet.count(tx.GetHash()) != 0;
if (fExisted && !fUpdate) return false;
if (fExisted || IsMine(tx) || IsFromMe(tx))
@@ -747,9 +768,57 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
return false;
}
+void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
+{
+ LOCK2(cs_main, cs_wallet);
+
+ CBlockIndex* pindex;
+ assert(mapBlockIndex.count(hashBlock));
+ pindex = mapBlockIndex[hashBlock];
+ int conflictconfirms = 0;
+ if (chainActive.Contains(pindex)) {
+ conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1);
+ }
+ assert(conflictconfirms < 0);
+
+ // Do not flush the wallet here for performance reasons
+ CWalletDB walletdb(strWalletFile, "r+", false);
+
+ std::deque<uint256> todo;
+ std::set<uint256> done;
+
+ todo.push_back(hashTx);
+
+ while (!todo.empty()) {
+ uint256 now = todo.front();
+ todo.pop_front();
+ done.insert(now);
+ assert(mapWallet.count(now));
+ CWalletTx& wtx = mapWallet[now];
+ int currentconfirm = wtx.GetDepthInMainChain();
+ if (conflictconfirms < currentconfirm) {
+ // Block is 'more conflicted' than current confirm; update.
+ // Mark transaction as conflicted with this block.
+ wtx.nIndex = -1;
+ wtx.hashBlock = hashBlock;
+ wtx.MarkDirty();
+ wtx.WriteToDisk(&walletdb);
+ // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
+ TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
+ while (iter != mapTxSpends.end() && iter->first.hash == now) {
+ if (!done.count(iter->second)) {
+ todo.push_back(iter->second);
+ }
+ iter++;
+ }
+ }
+ }
+}
+
void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
{
LOCK2(cs_main, cs_wallet);
+
if (!AddToWalletIfInvolvingMe(tx, pblock, true))
return; // Not one of ours
@@ -1089,7 +1158,7 @@ void CWallet::ReacceptWalletTransactions()
int nDepth = wtx.GetDepthInMainChain();
- if (!wtx.IsCoinBase() && nDepth < 0) {
+ if (!wtx.IsCoinBase() && nDepth == 0) {
mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
}
}
@@ -1303,6 +1372,14 @@ bool CWalletTx::IsTrusted() const
if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
return false;
+ // Don't trust unconfirmed transactions from us unless they are in the mempool.
+ {
+ LOCK(mempool.cs);
+ if (!mempool.exists(GetHash())) {
+ return false;
+ }
+ }
+
// Trusted if all inputs are from us and are in the mempool:
BOOST_FOREACH(const CTxIn& txin, vin)
{
@@ -1879,6 +1956,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
//a chance at a free transaction.
//But mempool inputs might still be in the mempool, so their age stays 0
int age = pcoin.first->GetDepthInMainChain();
+ assert(age >= 0);
if (age != 0)
age += 1;
dPriority += (double)nCredit * age;
@@ -2017,6 +2095,9 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
}
CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
+ if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) {
+ nFeeNeeded = coinControl->nMinimumTotalFee;
+ }
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
// because we must be at the maximum allowed fee.
@@ -2112,9 +2193,6 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge
{
// payTxFee is user-set "I want to pay this much"
CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
- // user selected total at least (default=true)
- if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
- nFeeNeeded = payTxFee.GetFeePerK();
// User didn't set: use -txconfirmtarget to estimate...
if (nFeeNeeded == 0) {
int estimateFoundTarget = nConfirmTarget;
@@ -2814,9 +2892,9 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block)
return chainActive.Height() - pindex->nHeight + 1;
}
-int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
+int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
{
- if (hashBlock.IsNull() || nIndex == -1)
+ if (hashBlock.IsNull())
return 0;
AssertLockHeld(cs_main);
@@ -2829,17 +2907,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
return 0;
pindexRet = pindex;
- return chainActive.Height() - pindex->nHeight + 1;
-}
-
-int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
-{
- AssertLockHeld(cs_main);
- int nResult = GetDepthInMainChainINTERNAL(pindexRet);
- if (nResult == 0 && !mempool.exists(GetHash()))
- return -1; // Not in chain, not in mempool
-
- return nResult;
+ return ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1);
}
int CMerkleTx::GetBlocksToMaturity() const
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index a4199488fc..859788893c 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -35,7 +35,6 @@ extern CAmount maxTxFee;
extern unsigned int nTxConfirmTarget;
extern bool bSpendZeroConfChange;
extern bool fSendFreeTransactions;
-extern bool fPayAtLeastCustomFee;
static const unsigned int DEFAULT_KEYPOOL_SIZE = 100;
//! -paytxfee default
@@ -156,11 +155,14 @@ struct COutputEntry
/** A transaction with a merkle branch linking it to the block chain. */
class CMerkleTx : public CTransaction
{
-private:
- int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
-
public:
uint256 hashBlock;
+
+ /* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
+ * block in the chain we know this or any in-wallet dependency conflicts
+ * with. Older clients interpret nIndex == -1 as unconfirmed for backward
+ * compatibility.
+ */
int nIndex;
CMerkleTx()
@@ -193,16 +195,15 @@ public:
int SetMerkleBranch(const CBlock& block);
-
/**
* Return depth of transaction in blockchain:
- * -1 : not in blockchain, and not in memory pool (conflicted transaction)
+ * <0 : conflicts with a transaction this deep in the blockchain
* 0 : in memory pool, waiting to be included in a block
* >=1 : this many blocks deep in the main chain
*/
int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
- bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
+ bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
int GetBlocksToMaturity() const;
bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
};
@@ -481,6 +482,10 @@ private:
void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
void AddToSpends(const uint256& wtxid);
+ /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
+ void MarkConflicted(const uint256& hashBlock, const uint256& hashTx);
+
+
void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>);
public:
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 5c08ee6d6c..e2e827d816 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -113,19 +113,19 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript)
{
nWalletDBUpdated++;
- return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false);
+ return Write(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false);
}
bool CWalletDB::WriteWatchOnly(const CScript &dest)
{
nWalletDBUpdated++;
- return Write(std::make_pair(std::string("watchs"), dest), '1');
+ return Write(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1');
}
bool CWalletDB::EraseWatchOnly(const CScript &dest)
{
nWalletDBUpdated++;
- return Erase(std::make_pair(std::string("watchs"), dest));
+ return Erase(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)));
}
bool CWalletDB::WriteBestBlock(const CBlockLocator& locator)
@@ -421,7 +421,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
else if (strType == "watchs")
{
CScript script;
- ssKey >> script;
+ ssKey >> *(CScriptBase*)(&script);
char fYes;
ssValue >> fYes;
if (fYes == '1')
@@ -575,7 +575,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
uint160 hash;
ssKey >> hash;
CScript script;
- ssValue >> script;
+ ssValue >> *(CScriptBase*)(&script);
if (!pwallet->LoadCScript(script))
{
strErr = "Error reading wallet database: LoadCScript failed";