aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bitcoin-tx.cpp13
-rw-r--r--src/bitcoind.cpp7
-rw-r--r--src/init.cpp2
-rw-r--r--src/interfaces/wallet.cpp1
-rw-r--r--src/interfaces/wallet.h3
-rw-r--r--src/net.cpp8
-rw-r--r--src/net.h2
-rw-r--r--src/netaddress.h10
-rw-r--r--src/netbase.cpp20
-rw-r--r--src/netbase.h2
-rw-r--r--src/policy/policy.cpp2
-rw-r--r--src/qt/optionsmodel.cpp23
-rw-r--r--src/qt/walletview.cpp11
-rw-r--r--src/rpc/client.cpp1
-rw-r--r--src/rpc/mining.cpp6
-rw-r--r--src/rpc/rawtransaction.cpp5
-rw-r--r--src/script/interpreter.cpp8
-rw-r--r--src/script/interpreter.h4
-rw-r--r--src/script/ismine.cpp2
-rw-r--r--src/script/script.h9
-rw-r--r--src/script/sign.cpp91
-rw-r--r--src/script/sign.h24
-rw-r--r--src/script/standard.cpp4
-rw-r--r--src/serialize.h48
-rw-r--r--src/test/addrman_tests.cpp66
-rw-r--r--src/test/allocator_tests.cpp4
-rw-r--r--src/test/bloom_tests.cpp2
-rw-r--r--src/test/checkqueue_tests.cpp2
-rw-r--r--src/test/coins_tests.cpp10
-rw-r--r--src/test/crypto_tests.cpp4
-rw-r--r--src/test/dbwrapper_tests.cpp6
-rw-r--r--src/test/hash_tests.cpp32
-rw-r--r--src/test/main_tests.cpp2
-rw-r--r--src/test/mempool_tests.cpp20
-rw-r--r--src/test/merkleblock_tests.cpp14
-rw-r--r--src/test/miner_tests.cpp4
-rw-r--r--src/test/pow_tests.cpp8
-rw-r--r--src/test/random_tests.cpp2
-rw-r--r--src/test/rpc_tests.cpp6
-rw-r--r--src/test/script_standard_tests.cpp24
-rw-r--r--src/test/serialize_tests.cpp54
-rw-r--r--src/test/torcontrol_tests.cpp4
-rw-r--r--src/test/txvalidationcache_tests.cpp10
-rw-r--r--src/test/util_tests.cpp11
-rw-r--r--src/util.h16
-rw-r--r--src/utiltime.cpp29
-rw-r--r--src/utiltime.h2
-rw-r--r--src/validation.cpp20
-rw-r--r--src/validation.h5
-rw-r--r--src/wallet/rpcdump.cpp44
-rw-r--r--src/wallet/rpcwallet.cpp203
-rw-r--r--src/wallet/test/wallet_tests.cpp22
-rw-r--r--src/wallet/wallet.cpp15
-rw-r--r--src/wallet/wallet.h5
-rw-r--r--src/wallet/walletdb.cpp14
-rw-r--r--src/wallet/walletdb.h1
56 files changed, 613 insertions, 354 deletions
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index deb8212a8f..07ad09ea7b 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -545,12 +545,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
if (!findSighashFlags(nHashType, flagStr))
throw std::runtime_error("unknown sighash flag/sign option");
- std::vector<CTransaction> txVariants;
- txVariants.push_back(tx);
-
// mergedTx will end up with all the signatures; it
// starts as a clone of the raw tx:
- CMutableTransaction mergedTx(txVariants[0]);
+ CMutableTransaction mergedTx{tx};
+ const CTransaction txv{tx};
CCoinsView viewDummy;
CCoinsViewCache view(&viewDummy);
@@ -633,7 +631,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
// Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
- CTxIn& txin = mergedTx.vin[i];
+ const CTxIn& txin = mergedTx.vin[i];
const Coin& coin = view.AccessCoin(txin.prevout);
if (coin.IsSpent()) {
continue;
@@ -644,11 +642,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
SignatureData sigdata;
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mergedTx.vout.size()))
- ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata);
+ ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
// ... and merge in other signatures:
- for (const CTransaction& txv : txVariants)
- sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i));
+ sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i));
UpdateTransaction(mergedTx, i, sigdata);
}
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 4aa811b86b..83d9719df2 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -139,6 +139,10 @@ bool AppInit(int argc, char* argv[])
if (gArgs.GetBoolArg("-daemon", false))
{
#if HAVE_DECL_DAEMON
+#if defined(MAC_OSX)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
fprintf(stdout, "Bitcoin server starting\n");
// Daemonize
@@ -146,6 +150,9 @@ bool AppInit(int argc, char* argv[])
fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno));
return false;
}
+#if defined(MAC_OSX)
+#pragma GCC diagnostic pop
+#endif
#else
fprintf(stderr, "Error: -daemon is not supported on this operating system\n");
return false;
diff --git a/src/init.cpp b/src/init.cpp
index 8db1b922c4..abff5ec79d 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -323,7 +323,7 @@ void OnRPCStopped()
{
uiInterface.NotifyBlockTip.disconnect(&RPCNotifyBlockChange);
RPCNotifyBlockChange(false, nullptr);
- cvBlockChange.notify_all();
+ g_best_block_cv.notify_all();
LogPrint(BCLog::RPC, "RPC stopped.\n");
}
diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
index fbf631f7da..3e6f0d6728 100644
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -130,6 +130,7 @@ public:
{
return m_wallet.ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase);
}
+ void abortRescan() override { m_wallet.AbortRescan(); }
bool backupWallet(const std::string& filename) override { return m_wallet.BackupWallet(filename); }
std::string getWalletName() override { return m_wallet.GetName(); }
bool getKeyFromPool(bool internal, CPubKey& pub_key) override
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index 3e27242c2c..dfe3d5f711 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -65,6 +65,9 @@ public:
virtual bool changeWalletPassphrase(const SecureString& old_wallet_passphrase,
const SecureString& new_wallet_passphrase) = 0;
+ //! Abort a rescan.
+ virtual void abortRescan() = 0;
+
//! Back up wallet.
virtual bool backupWallet(const std::string& filename) = 0;
diff --git a/src/net.cpp b/src/net.cpp
index 342dfbaeb9..356a66563f 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -124,7 +124,7 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
return nBestScore >= 0;
}
-//! Convert the pnSeeds6 array into usable address objects.
+//! Convert the pnSeed6 array into usable address objects.
static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
{
// It'll only connect to one or two seed nodes because once it connects,
@@ -368,7 +368,7 @@ static CAddress GetBindAddress(SOCKET sock)
return addr_bind;
}
-CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
+CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection)
{
if (pszDest == nullptr) {
if (IsLocal(addrConnect))
@@ -432,7 +432,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (hSocket == INVALID_SOCKET) {
return nullptr;
}
- connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
+ connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
}
if (!proxyConnectionFailed) {
// If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
@@ -1992,7 +1992,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
} else if (FindNode(std::string(pszDest)))
return;
- CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure);
+ CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection);
if (!pnode)
return;
diff --git a/src/net.h b/src/net.h
index 7839b75a86..1bcc3cbb44 100644
--- a/src/net.h
+++ b/src/net.h
@@ -338,7 +338,7 @@ private:
CNode* FindNode(const CService& addr);
bool AttemptToEvictConnection();
- CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure);
+ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection);
bool IsWhitelistedRange(const CNetAddr &addr);
void DeleteNode(CNode* pnode);
diff --git a/src/netaddress.h b/src/netaddress.h
index b3d1407f72..38f8709257 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -141,7 +141,7 @@ class CSubNet
class CService : public CNetAddr
{
protected:
- unsigned short port; // host order
+ uint16_t port; // host order
public:
CService();
@@ -168,13 +168,7 @@ class CService : public CNetAddr
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(ip);
-
- // TODO: introduce native support for BE serialization in serialize.h
- unsigned short portN = htons(port);
- READWRITE(Span<unsigned char>((unsigned char*)&portN, 2));
- if (ser_action.ForRead()) {
- port = ntohs(portN);
- }
+ READWRITE(WrapBigEndian(port));
}
};
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 92ac1c4c85..5d3d2f25c8 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -9,6 +9,7 @@
#include <sync.h>
#include <uint256.h>
#include <random.h>
+#include <tinyformat.h>
#include <util.h>
#include <utilstrencodings.h>
@@ -468,7 +469,17 @@ SOCKET CreateSocket(const CService &addrConnect)
return hSocket;
}
-bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, int nTimeout)
+template<typename... Args>
+static void LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args) {
+ std::string error_message = tfm::format(fmt, args...);
+ if (manual_connection) {
+ LogPrintf("%s\n", error_message);
+ } else {
+ LogPrint(BCLog::NET, "%s\n", error_message);
+ }
+}
+
+bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, int nTimeout, bool manual_connection)
{
struct sockaddr_storage sockaddr;
socklen_t len = sizeof(sockaddr);
@@ -513,7 +524,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
}
if (nRet != 0)
{
- LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet));
+ LogConnectFailure(manual_connection, "connect() to %s failed after select(): %s", addrConnect.ToString(), NetworkErrorString(nRet));
return false;
}
}
@@ -523,7 +534,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
else
#endif
{
- LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
+ LogConnectFailure(manual_connection, "connect() to %s failed: %s", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
return false;
}
}
@@ -581,7 +592,7 @@ bool IsProxy(const CNetAddr &addr) {
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocket, int nTimeout, bool *outProxyConnectionFailed)
{
// first connect to proxy server
- if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) {
+ if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout, true)) {
if (outProxyConnectionFailed)
*outProxyConnectionFailed = true;
return false;
@@ -601,6 +612,7 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int
}
return true;
}
+
bool LookupSubNet(const char* pszName, CSubNet& ret)
{
std::string strSubnet(pszName);
diff --git a/src/netbase.h b/src/netbase.h
index c0921b6441..50d4bc54fa 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -52,7 +52,7 @@ bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault,
CService LookupNumeric(const char *pszName, int portDefault = 0);
bool LookupSubNet(const char *pszName, CSubNet& subnet);
SOCKET CreateSocket(const CService &addrConnect);
-bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocketRet, int nTimeout);
+bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocketRet, int nTimeout, bool manual_connection);
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed);
/** Return readable error string for a network error code */
std::string NetworkErrorString(int err);
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index c3f65fb2ab..5963bf371a 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -230,7 +230,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
return false;
// Check P2WSH standard limits
- if (witnessversion == 0 && witnessprogram.size() == 32) {
+ if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
if (tx.vin[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
return false;
size_t sizeWitnessStack = tx.vin[i].scriptWitness.stack.size() - 1;
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 30c8124c58..cae9dace4c 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -24,6 +24,8 @@
const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1";
+static const QString GetDefaultProxyAddress();
+
OptionsModel::OptionsModel(interfaces::Node& node, QObject *parent, bool resetSettings) :
QAbstractListModel(parent), m_node(node)
{
@@ -121,7 +123,7 @@ void OptionsModel::Init(bool resetSettings)
if (!settings.contains("fUseProxy"))
settings.setValue("fUseProxy", false);
if (!settings.contains("addrProxy"))
- settings.setValue("addrProxy", QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST, DEFAULT_GUI_PROXY_PORT));
+ settings.setValue("addrProxy", GetDefaultProxyAddress());
// Only try to set -proxy, if user has enabled fUseProxy
if (settings.value("fUseProxy").toBool() && !m_node.softSetArg("-proxy", settings.value("addrProxy").toString().toStdString()))
addOverriddenOption("-proxy");
@@ -131,7 +133,7 @@ void OptionsModel::Init(bool resetSettings)
if (!settings.contains("fUseSeparateProxyTor"))
settings.setValue("fUseSeparateProxyTor", false);
if (!settings.contains("addrSeparateProxyTor"))
- settings.setValue("addrSeparateProxyTor", QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST, DEFAULT_GUI_PROXY_PORT));
+ settings.setValue("addrSeparateProxyTor", GetDefaultProxyAddress());
// Only try to set -onion, if user has enabled fUseSeparateProxyTor
if (settings.value("fUseSeparateProxyTor").toBool() && !m_node.softSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString()))
addOverriddenOption("-onion");
@@ -223,6 +225,11 @@ static void SetProxySetting(QSettings &settings, const QString &name, const Prox
settings.setValue(name, ip_port.ip + ":" + ip_port.port);
}
+static const QString GetDefaultProxyAddress()
+{
+ return QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST).arg(DEFAULT_GUI_PROXY_PORT);
+}
+
// read QSettings values and return them
QVariant OptionsModel::data(const QModelIndex & index, int role) const
{
@@ -485,4 +492,16 @@ void OptionsModel::checkAndMigrate()
settings.setValue(strSettingsVersionKey, CLIENT_VERSION);
}
+
+ // Overwrite the 'addrProxy' setting in case it has been set to an illegal
+ // default value (see issue #12623; PR #12650).
+ if (settings.contains("addrProxy") && settings.value("addrProxy").toString().endsWith("%2")) {
+ settings.setValue("addrProxy", GetDefaultProxyAddress());
+ }
+
+ // Overwrite the 'addrSeparateProxyTor' setting in case it has been set to an illegal
+ // default value (see issue #12623; PR #12650).
+ if (settings.contains("addrSeparateProxyTor") && settings.value("addrSeparateProxyTor").toString().endsWith("%2")) {
+ settings.setValue("addrSeparateProxyTor", GetDefaultProxyAddress());
+ }
}
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index 8b9b85c8c9..d529595dec 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -315,9 +315,9 @@ void WalletView::showProgress(const QString &title, int nProgress)
progressDialog = new QProgressDialog(title, "", 0, 100);
progressDialog->setWindowModality(Qt::ApplicationModal);
progressDialog->setMinimumDuration(0);
- progressDialog->setCancelButton(0);
progressDialog->setAutoClose(false);
progressDialog->setValue(0);
+ progressDialog->setCancelButtonText(tr("Cancel"));
}
else if (nProgress == 100)
{
@@ -327,8 +327,13 @@ void WalletView::showProgress(const QString &title, int nProgress)
progressDialog->deleteLater();
}
}
- else if (progressDialog)
- progressDialog->setValue(nProgress);
+ else if (progressDialog) {
+ if (progressDialog->wasCanceled()) {
+ getWalletModel()->wallet().abortRescan();
+ } else {
+ progressDialog->setValue(nProgress);
+ }
+ }
}
void WalletView::requestedSyncWarningInfo()
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 01f932dbb4..34c41b3b6b 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -51,6 +51,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listreceivedbylabel", 0, "minconf" },
{ "listreceivedbylabel", 1, "include_empty" },
{ "listreceivedbylabel", 2, "include_watchonly" },
+ { "getlabeladdress", 1, "force" },
{ "getbalance", 1, "minconf" },
{ "getbalance", 2, "include_watchonly" },
{ "getblockhash", 0, "height" },
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 75bc983200..9a7c4b8e6d 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -471,10 +471,10 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
{
checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1);
- WaitableLock lock(csBestBlock);
- while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning())
+ WaitableLock lock(g_best_block_mutex);
+ while (g_best_block == hashWatchedChain && IsRPCRunning())
{
- if (cvBlockChange.wait_until(lock, checktxtime) == std::cv_status::timeout)
+ if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout)
{
// Timeout: Check transactions for update
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index f0493de3bd..543e4fc358 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -774,9 +774,6 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
if (is_temp_keystore && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
RPCTypeCheckObj(prevOut,
{
- {"txid", UniValueType(UniValue::VSTR)},
- {"vout", UniValueType(UniValue::VNUM)},
- {"scriptPubKey", UniValueType(UniValue::VSTR)},
{"redeemScript", UniValueType(UniValue::VSTR)},
});
UniValue v = find_value(prevOut, "redeemScript");
@@ -831,7 +828,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
SignatureData sigdata;
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mtx.vout.size())) {
- ProduceSignature(MutableTransactionSignatureCreator(keystore, &mtx, i, amount, nHashType), prevPubKey, sigdata);
+ ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, nHashType), prevPubKey, sigdata);
}
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i));
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 182f4a3327..338e07e24e 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1361,7 +1361,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
CScript scriptPubKey;
if (witversion == 0) {
- if (program.size() == 32) {
+ if (program.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
// Version 0 segregated witness program: SHA256(CScript) inside the program, CScript + inputs in witness
if (witness.stack.size() == 0) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY);
@@ -1373,7 +1373,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
if (memcmp(hashScriptPubKey.begin(), program.data(), 32)) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
}
- } else if (program.size() == 20) {
+ } else if (program.size() == WITNESS_V0_KEYHASH_SIZE) {
// Special case for pay-to-pubkeyhash; signature + pubkey in witness
if (witness.stack.size() != 2) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); // 2 items in witness
@@ -1530,10 +1530,10 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
size_t static WitnessSigOps(int witversion, const std::vector<unsigned char>& witprogram, const CScriptWitness& witness, int flags)
{
if (witversion == 0) {
- if (witprogram.size() == 20)
+ if (witprogram.size() == WITNESS_V0_KEYHASH_SIZE)
return 1;
- if (witprogram.size() == 32 && witness.stack.size() > 0) {
+ if (witprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE && witness.stack.size() > 0) {
CScript subscript(witness.stack.back().begin(), witness.stack.back().end());
return subscript.GetSigOpCount(true);
}
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index bb7750d783..601a4a866d 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -129,6 +129,10 @@ enum class SigVersion
WITNESS_V0 = 1,
};
+/** Signature hash sizes */
+static constexpr size_t WITNESS_V0_SCRIPTHASH_SIZE = 32;
+static constexpr size_t WITNESS_V0_KEYHASH_SIZE = 20;
+
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr);
class BaseSignatureChecker
diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp
index 05bc5e9bd6..b826bcfe20 100644
--- a/src/script/ismine.cpp
+++ b/src/script/ismine.cpp
@@ -146,7 +146,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool&
if (keystore.HaveWatchOnly(scriptPubKey)) {
// TODO: This could be optimized some by doing some work after the above solver
SignatureData sigs;
- return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
+ return ProduceSignature(keystore, DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
}
return ISMINE_NO;
}
diff --git a/src/script/script.h b/src/script/script.h
index 8e5a792c7d..59ceff247c 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -615,15 +615,6 @@ public:
return nFound;
}
- int Find(opcodetype op) const
- {
- int nFound = 0;
- opcodetype opcode;
- for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);)
- if (opcode == op)
- ++nFound;
- return nFound;
- }
/**
* Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 910bb39ce6..ac35f17f3e 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -14,12 +14,12 @@
typedef std::vector<unsigned char> valtype;
-TransactionSignatureCreator::TransactionSignatureCreator(const SigningProvider* provider, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(provider), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
+TransactionSignatureCreator::TransactionSignatureCreator(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
-bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
+bool TransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
{
CKey key;
- if (!m_provider->GetKey(address, key))
+ if (!provider.GetKey(address, key))
return false;
// Signing with uncompressed keys is disabled in witness scripts
@@ -33,16 +33,16 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
return true;
}
-static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
+static bool Sign1(const SigningProvider& provider, const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
{
std::vector<unsigned char> vchSig;
- if (!creator.CreateSig(vchSig, address, scriptCode, sigversion))
+ if (!creator.CreateSig(provider, vchSig, address, scriptCode, sigversion))
return false;
ret.push_back(vchSig);
return true;
}
-static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
+static bool SignN(const SigningProvider& provider, const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
{
int nSigned = 0;
int nRequired = multisigdata.front()[0];
@@ -50,7 +50,7 @@ static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureC
{
const valtype& pubkey = multisigdata[i];
CKeyID keyID = CPubKey(pubkey).GetID();
- if (Sign1(keyID, creator, scriptCode, ret, sigversion))
+ if (Sign1(provider, keyID, creator, scriptCode, ret, sigversion))
++nSigned;
}
return nSigned==nRequired;
@@ -62,7 +62,7 @@ static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureC
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
* Returns false if scriptPubKey could not be completely satisfied.
*/
-static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
+static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
{
CScript scriptRet;
@@ -82,20 +82,20 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
return false;
case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID();
- return Sign1(keyID, creator, scriptPubKey, ret, sigversion);
+ return Sign1(provider, keyID, creator, scriptPubKey, ret, sigversion);
case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
- if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
+ if (!Sign1(provider, keyID, creator, scriptPubKey, ret, sigversion))
return false;
else
{
CPubKey vch;
- creator.Provider().GetPubKey(keyID, vch);
+ provider.GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch));
}
return true;
case TX_SCRIPTHASH:
- if (creator.Provider().GetCScript(uint160(vSolutions[0]), scriptRet)) {
+ if (provider.GetCScript(uint160(vSolutions[0]), scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true;
}
@@ -103,7 +103,7 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
case TX_MULTISIG:
ret.push_back(valtype()); // workaround CHECKMULTISIG bug
- return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion));
+ return (SignN(provider, vSolutions, creator, scriptPubKey, ret, sigversion));
case TX_WITNESS_V0_KEYHASH:
ret.push_back(vSolutions[0]);
@@ -111,7 +111,7 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
case TX_WITNESS_V0_SCRIPTHASH:
CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
- if (creator.Provider().GetCScript(h160, scriptRet)) {
+ if (provider.GetCScript(h160, scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true;
}
@@ -137,11 +137,11 @@ static CScript PushAll(const std::vector<valtype>& values)
return result;
}
-bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
+bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
{
std::vector<valtype> result;
txnouttype whichType;
- bool solved = SignStep(creator, fromPubKey, result, whichType, SigVersion::BASE);
+ bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE);
bool P2SH = false;
CScript subscript;
sigdata.scriptWitness.stack.clear();
@@ -152,7 +152,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
// the final scriptSig is the signatures from that
// and then the serialized subscript:
subscript = CScript(result[0].begin(), result[0].end());
- solved = solved && SignStep(creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH;
+ solved = solved && SignStep(provider, creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH;
P2SH = true;
}
@@ -161,7 +161,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
CScript witnessscript;
witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
txnouttype subType;
- solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
+ solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
sigdata.scriptWitness.stack = result;
result.clear();
}
@@ -169,7 +169,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
{
CScript witnessscript(result[0].begin(), result[0].end());
txnouttype subType;
- solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
+ solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end()));
sigdata.scriptWitness.stack = result;
result.clear();
@@ -210,10 +210,10 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C
assert(nIn < txTo.vin.size());
CTransaction txToConst(txTo);
- TransactionSignatureCreator creator(&provider, &txToConst, nIn, amount, nHashType);
+ TransactionSignatureCreator creator(&txToConst, nIn, amount, nHashType);
SignatureData sigdata;
- bool ret = ProduceSignature(creator, fromPubKey, sigdata);
+ bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
UpdateTransaction(txTo, nIn, sigdata);
return ret;
}
@@ -392,39 +392,37 @@ SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignature
namespace {
/** Dummy signature checker which accepts all signatures. */
-class DummySignatureChecker : public BaseSignatureChecker
+class DummySignatureChecker final : public BaseSignatureChecker
{
public:
DummySignatureChecker() {}
+ bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; }
+};
+const DummySignatureChecker DUMMY_CHECKER;
- bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
+class DummySignatureCreator final : public BaseSignatureCreator {
+public:
+ DummySignatureCreator() {}
+ const BaseSignatureChecker& Checker() const override { return DUMMY_CHECKER; }
+ bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override
{
+ // Create a dummy signature that is a valid DER-encoding
+ vchSig.assign(72, '\000');
+ vchSig[0] = 0x30;
+ vchSig[1] = 69;
+ vchSig[2] = 0x02;
+ vchSig[3] = 33;
+ vchSig[4] = 0x01;
+ vchSig[4 + 33] = 0x02;
+ vchSig[5 + 33] = 32;
+ vchSig[6 + 33] = 0x01;
+ vchSig[6 + 33 + 32] = SIGHASH_ALL;
return true;
}
};
-const DummySignatureChecker dummyChecker;
-} // namespace
-
-const BaseSignatureChecker& DummySignatureCreator::Checker() const
-{
- return dummyChecker;
}
-bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
-{
- // Create a dummy signature that is a valid DER-encoding
- vchSig.assign(72, '\000');
- vchSig[0] = 0x30;
- vchSig[1] = 69;
- vchSig[2] = 0x02;
- vchSig[3] = 33;
- vchSig[4] = 0x01;
- vchSig[4 + 33] = 0x02;
- vchSig[5 + 33] = 32;
- vchSig[6 + 33] = 0x01;
- vchSig[6 + 33 + 32] = SIGHASH_ALL;
- return true;
-}
+const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator();
bool IsSolvable(const SigningProvider& provider, const CScript& script)
{
@@ -432,14 +430,13 @@ bool IsSolvable(const SigningProvider& provider, const CScript& script)
// if we were to have the private keys. This is just to make sure that the script is valid and that,
// if found in a transaction, we would still accept and relay that transaction. In particular,
// it will reject witness outputs that require signing with an uncompressed public key.
- DummySignatureCreator creator(&provider);
SignatureData sigs;
// Make sure that STANDARD_SCRIPT_VERIFY_FLAGS includes SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, the most
// important property this function is designed to test for.
static_assert(STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, "IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE");
- if (ProduceSignature(creator, script, sigs)) {
+ if (ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, script, sigs)) {
// VerifyScript check is just defensive, and should never fail.
- assert(VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()));
+ assert(VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, DUMMY_CHECKER));
return true;
}
return false;
diff --git a/src/script/sign.h b/src/script/sign.h
index c301f0544f..cf3651c1de 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -26,19 +26,14 @@ public:
virtual bool GetKey(const CKeyID &address, CKey& key) const =0;
};
-/** Virtual base class for signature creators. */
+/** Interface for signature creators. */
class BaseSignatureCreator {
-protected:
- const SigningProvider* m_provider;
-
public:
- explicit BaseSignatureCreator(const SigningProvider* provider) : m_provider(provider) {}
- const SigningProvider& Provider() const { return *m_provider; }
virtual ~BaseSignatureCreator() {}
virtual const BaseSignatureChecker& Checker() const =0;
/** Create a singular (non-script) signature. */
- virtual bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0;
+ virtual bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0;
};
/** A signature creator for transactions. */
@@ -50,25 +45,20 @@ class TransactionSignatureCreator : public BaseSignatureCreator {
const TransactionSignatureChecker checker;
public:
- TransactionSignatureCreator(const SigningProvider* provider, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL);
+ TransactionSignatureCreator(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL);
const BaseSignatureChecker& Checker() const override { return checker; }
- bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
+ bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
};
class MutableTransactionSignatureCreator : public TransactionSignatureCreator {
CTransaction tx;
public:
- MutableTransactionSignatureCreator(const SigningProvider* provider, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : TransactionSignatureCreator(provider, &tx, nInIn, amountIn, nHashTypeIn), tx(*txToIn) {}
+ MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : TransactionSignatureCreator(&tx, nInIn, amountIn, nHashTypeIn), tx(*txToIn) {}
};
/** A signature creator that just produces 72-byte empty signatures. */
-class DummySignatureCreator : public BaseSignatureCreator {
-public:
- explicit DummySignatureCreator(const SigningProvider* provider) : BaseSignatureCreator(provider) {}
- const BaseSignatureChecker& Checker() const override;
- bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
-};
+extern const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR;
struct SignatureData {
CScript scriptSig;
@@ -79,7 +69,7 @@ struct SignatureData {
};
/** Produce a script signature using a generic signature creator. */
-bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
+bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
/** Produce a script signature for a transaction. */
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 0b9053d7fc..76778112aa 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -66,12 +66,12 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
int witnessversion;
std::vector<unsigned char> witnessprogram;
if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
- if (witnessversion == 0 && witnessprogram.size() == 20) {
+ if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
typeRet = TX_WITNESS_V0_KEYHASH;
vSolutionsRet.push_back(witnessprogram);
return true;
}
- if (witnessversion == 0 && witnessprogram.size() == 32) {
+ if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
typeRet = TX_WITNESS_V0_SCRIPTHASH;
vSolutionsRet.push_back(witnessprogram);
return true;
diff --git a/src/serialize.h b/src/serialize.h
index 57e434faf1..e54c7483d2 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -79,6 +79,11 @@ template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
obj = htole16(obj);
s.write((char*)&obj, 2);
}
+template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
+{
+ obj = htobe16(obj);
+ s.write((char*)&obj, 2);
+}
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
{
obj = htole32(obj);
@@ -101,6 +106,12 @@ template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
s.read((char*)&obj, 2);
return le16toh(obj);
}
+template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
+{
+ uint16_t obj;
+ s.read((char*)&obj, 2);
+ return be16toh(obj);
+}
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
{
uint32_t obj;
@@ -416,6 +427,40 @@ public:
}
};
+/** Serialization wrapper class for big-endian integers.
+ *
+ * Use this wrapper around integer types that are stored in memory in native
+ * byte order, but serialized in big endian notation. This is only intended
+ * to implement serializers that are compatible with existing formats, and
+ * its use is not recommended for new data structures.
+ *
+ * Only 16-bit types are supported for now.
+ */
+template<typename I>
+class BigEndian
+{
+protected:
+ I& m_val;
+public:
+ explicit BigEndian(I& val) : m_val(val)
+ {
+ static_assert(std::is_unsigned<I>::value, "BigEndian type must be unsigned integer");
+ static_assert(sizeof(I) == 2 && std::numeric_limits<I>::min() == 0 && std::numeric_limits<I>::max() == std::numeric_limits<uint16_t>::max(), "Unsupported BigEndian size");
+ }
+
+ template<typename Stream>
+ void Serialize(Stream& s) const
+ {
+ ser_writedata16be(s, m_val);
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream& s)
+ {
+ m_val = ser_readdata16be(s);
+ }
+};
+
class CCompactSize
{
protected:
@@ -466,6 +511,9 @@ public:
template<VarIntMode Mode=VarIntMode::DEFAULT, typename I>
CVarInt<Mode, I> WrapVarInt(I& n) { return CVarInt<Mode, I>{n}; }
+template<typename I>
+BigEndian<I> WrapBigEndian(I& n) { return BigEndian<I>(n); }
+
/**
* Forward declarations
*/
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index 6b188a06b4..ee3650d148 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -98,14 +98,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
CNetAddr source = ResolveIP("252.2.2.2");
// Test: Does Addrman respond correctly when empty.
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
CAddrInfo addr_null = addrman.Select();
BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0");
// Test: Does Addrman::Add work as expected.
CService addr1 = ResolveService("250.1.1.1", 8333);
BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
CAddrInfo addr_ret1 = addrman.Select();
BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333");
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
// Expected dup IP should not be added.
CService addr1_dup = ResolveService("250.1.1.1", 8333);
BOOST_CHECK(!addrman.Add(CAddress(addr1_dup, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
// Test: New table has one addr and we add a diff addr we should
@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
// Test: AddrMan::Clear() should empty the new table.
addrman.Clear();
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
CAddrInfo addr_null2 = addrman.Select();
BOOST_CHECK_EQUAL(addr_null2.ToString(), "[::]:0");
@@ -146,23 +146,23 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
// Test 7; Addr with same IP but diff port does not replace existing addr.
CService addr1 = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
CService addr1_port = ResolveService("250.1.1.1", 8334);
addrman.Add(CAddress(addr1_port, NODE_NONE), source);
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
CAddrInfo addr_ret2 = addrman.Select();
BOOST_CHECK_EQUAL(addr_ret2.ToString(), "250.1.1.1:8333");
// Test: Add same IP but diff port to tried table, it doesn't get added.
// Perhaps this is not ideal behavior but it is the current behavior.
addrman.Good(CAddress(addr1_port, NODE_NONE));
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
bool newOnly = true;
CAddrInfo addr_ret3 = addrman.Select(newOnly);
BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
@@ -178,7 +178,7 @@ BOOST_AUTO_TEST_CASE(addrman_select)
// Test: Select from new with 1 addr in new.
CService addr1 = ResolveService("250.1.1.1", 8333);
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
bool newOnly = true;
CAddrInfo addr_ret1 = addrman.Select(newOnly);
@@ -186,14 +186,14 @@ BOOST_AUTO_TEST_CASE(addrman_select)
// Test: move addr to tried, select from new expected nothing returned.
addrman.Good(CAddress(addr1, NODE_NONE));
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
CAddrInfo addr_ret2 = addrman.Select(newOnly);
BOOST_CHECK_EQUAL(addr_ret2.ToString(), "[::]:0");
CAddrInfo addr_ret3 = addrman.Select();
BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
// Add three addresses to new table.
@@ -218,14 +218,14 @@ BOOST_AUTO_TEST_CASE(addrman_select)
addrman.Good(CAddress(addr7, NODE_NONE));
// Test: 6 addrs + 1 addr from last test = 7.
- BOOST_CHECK_EQUAL(addrman.size(), 7);
+ BOOST_CHECK_EQUAL(addrman.size(), 7U);
// Test: Select pulls from new and tried regardless of port number.
std::set<uint16_t> ports;
for (int i = 0; i < 20; ++i) {
ports.insert(addrman.Select().GetPort());
}
- BOOST_CHECK_EQUAL(ports.size(), 3);
+ BOOST_CHECK_EQUAL(ports.size(), 3U);
}
BOOST_AUTO_TEST_CASE(addrman_new_collisions)
@@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
for (unsigned int i = 1; i < 18; i++) {
CService addr = ResolveService("250.1.1." + std::to_string(i));
@@ -247,11 +247,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
//Test: new table collision!
CService addr1 = ResolveService("250.1.1.18");
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK_EQUAL(addrman.size(), 17);
+ BOOST_CHECK_EQUAL(addrman.size(), 17U);
CService addr2 = ResolveService("250.1.1.19");
addrman.Add(CAddress(addr2, NODE_NONE), source);
- BOOST_CHECK_EQUAL(addrman.size(), 18);
+ BOOST_CHECK_EQUAL(addrman.size(), 18U);
}
BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
@@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
for (unsigned int i = 1; i < 80; i++) {
CService addr = ResolveService("250.1.1." + std::to_string(i));
@@ -274,18 +274,18 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
//Test: tried table collision!
CService addr1 = ResolveService("250.1.1.80");
addrman.Add(CAddress(addr1, NODE_NONE), source);
- BOOST_CHECK_EQUAL(addrman.size(), 79);
+ BOOST_CHECK_EQUAL(addrman.size(), 79U);
CService addr2 = ResolveService("250.1.1.81");
addrman.Add(CAddress(addr2, NODE_NONE), source);
- BOOST_CHECK_EQUAL(addrman.size(), 80);
+ BOOST_CHECK_EQUAL(addrman.size(), 80U);
}
BOOST_AUTO_TEST_CASE(addrman_find)
{
CAddrManTest addrman;
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE);
@@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(addrman_create)
{
CAddrManTest addrman;
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
CNetAddr source1 = ResolveIP("250.1.2.1");
@@ -338,7 +338,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete)
{
CAddrManTest addrman;
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE);
CNetAddr source1 = ResolveIP("250.1.2.1");
@@ -347,9 +347,9 @@ BOOST_AUTO_TEST_CASE(addrman_delete)
addrman.Create(addr1, source1, &nId);
// Test: Delete should actually delete the addr.
- BOOST_CHECK_EQUAL(addrman.size(), 1);
+ BOOST_CHECK_EQUAL(addrman.size(), 1U);
addrman.Delete(nId);
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
CAddrInfo* info2 = addrman.Find(addr1);
BOOST_CHECK(info2 == nullptr);
}
@@ -360,9 +360,9 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
// Test: Sanity check, GetAddr should never return anything if addrman
// is empty.
- BOOST_CHECK_EQUAL(addrman.size(), 0);
+ BOOST_CHECK_EQUAL(addrman.size(), 0U);
std::vector<CAddress> vAddr1 = addrman.GetAddr();
- BOOST_CHECK_EQUAL(vAddr1.size(), 0);
+ BOOST_CHECK_EQUAL(vAddr1.size(), 0U);
CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE);
addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false
@@ -385,12 +385,12 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
addrman.Add(addr5, source1);
// GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down.
- BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1);
+ BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1U);
// Test: Ensure GetAddr works with new and tried addresses.
addrman.Good(CAddress(addr1, NODE_NONE));
addrman.Good(CAddress(addr2, NODE_NONE));
- BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1);
+ BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1U);
// Test: Ensure GetAddr still returns 23% when addrman has many addrs.
for (unsigned int i = 1; i < (8 * 256); i++) {
@@ -409,9 +409,9 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
size_t percent23 = (addrman.size() * 23) / 100;
BOOST_CHECK_EQUAL(vAddr.size(), percent23);
- BOOST_CHECK_EQUAL(vAddr.size(), 461);
+ BOOST_CHECK_EQUAL(vAddr.size(), 461U);
// (Addrman.size() < number of addresses added) due to address collisions.
- BOOST_CHECK_EQUAL(addrman.size(), 2006);
+ BOOST_CHECK_EQUAL(addrman.size(), 2006U);
}
@@ -454,7 +454,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
}
// Test: IP addresses in the same group (\16 prefix for IPv4) should
// never get more than 8 buckets
- BOOST_CHECK_EQUAL(buckets.size(), 8);
+ BOOST_CHECK_EQUAL(buckets.size(), 8U);
buckets.clear();
for (int j = 0; j < 255; j++) {
@@ -466,7 +466,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
}
// Test: IP addresses in the different groups should map to more than
// 8 buckets.
- BOOST_CHECK_EQUAL(buckets.size(), 160);
+ BOOST_CHECK_EQUAL(buckets.size(), 160U);
}
BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
@@ -506,7 +506,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
}
// Test: IP addresses in the same group (\16 prefix for IPv4) should
// always map to the same bucket.
- BOOST_CHECK_EQUAL(buckets.size(), 1);
+ BOOST_CHECK_EQUAL(buckets.size(), 1U);
buckets.clear();
for (int j = 0; j < 4 * 255; j++) {
diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp
index 24cd88c7a7..67d1229c70 100644
--- a/src/test/allocator_tests.cpp
+++ b/src/test/allocator_tests.cpp
@@ -64,10 +64,10 @@ BOOST_AUTO_TEST_CASE(arena_tests)
BOOST_CHECK(b.stats().used == 128);
b.free(a3);
BOOST_CHECK(b.stats().used == 0);
- BOOST_CHECK_EQUAL(b.stats().chunks_used, 0);
+ BOOST_CHECK_EQUAL(b.stats().chunks_used, 0U);
BOOST_CHECK(b.stats().total == synth_size);
BOOST_CHECK(b.stats().free == synth_size);
- BOOST_CHECK_EQUAL(b.stats().chunks_free, 1);
+ BOOST_CHECK_EQUAL(b.stats().chunks_free, 1U);
std::vector<void*> addr;
BOOST_CHECK(b.alloc(0) == nullptr); // allocating 0 always returns nullptr
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 73c8eb5168..17f3004ef3 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex());
- BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1);
+ BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1U);
std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index 8e0ec5243b..de47216449 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory)
control.Add(vChecks);
}
}
- BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0);
+ BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0U);
}
tg.interrupt_all();
tg.join_all();
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index de7d8f7b90..a146c69fd2 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -480,8 +480,8 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization)
Coin cc1;
ss1 >> cc1;
BOOST_CHECK_EQUAL(cc1.fCoinBase, false);
- BOOST_CHECK_EQUAL(cc1.nHeight, 203998);
- BOOST_CHECK_EQUAL(cc1.out.nValue, 60000000000ULL);
+ BOOST_CHECK_EQUAL(cc1.nHeight, 203998U);
+ BOOST_CHECK_EQUAL(cc1.out.nValue, CAmount{60000000000});
BOOST_CHECK_EQUAL(HexStr(cc1.out.scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("816115944e077fe7c803cfa57f29b36bf87c1d35"))))));
// Good example
@@ -489,7 +489,7 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization)
Coin cc2;
ss2 >> cc2;
BOOST_CHECK_EQUAL(cc2.fCoinBase, true);
- BOOST_CHECK_EQUAL(cc2.nHeight, 120891);
+ BOOST_CHECK_EQUAL(cc2.nHeight, 120891U);
BOOST_CHECK_EQUAL(cc2.out.nValue, 110397);
BOOST_CHECK_EQUAL(HexStr(cc2.out.scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("8c988f1a4a4de2161e0f50aac7f17e7f9555caa4"))))));
@@ -498,9 +498,9 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization)
Coin cc3;
ss3 >> cc3;
BOOST_CHECK_EQUAL(cc3.fCoinBase, false);
- BOOST_CHECK_EQUAL(cc3.nHeight, 0);
+ BOOST_CHECK_EQUAL(cc3.nHeight, 0U);
BOOST_CHECK_EQUAL(cc3.out.nValue, 0);
- BOOST_CHECK_EQUAL(cc3.out.scriptPubKey.size(), 0);
+ BOOST_CHECK_EQUAL(cc3.out.scriptPubKey.size(), 0U);
// scriptPubKey that ends beyond the end of the stream
CDataStream ss4(ParseHex("000007"), SER_DISK, CLIENT_VERSION);
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index cdfc664d56..de0d72614b 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -527,10 +527,10 @@ BOOST_AUTO_TEST_CASE(chacha20_testvector)
BOOST_AUTO_TEST_CASE(countbits_tests)
{
FastRandomContext ctx;
- for (int i = 0; i <= 64; ++i) {
+ for (unsigned int i = 0; i <= 64; ++i) {
if (i == 0) {
// Check handling of zero.
- BOOST_CHECK_EQUAL(CountBits(0), 0);
+ BOOST_CHECK_EQUAL(CountBits(0), 0U);
} else if (i < 10) {
for (uint64_t j = 1 << (i - 1); (j >> i) == 0; ++j) {
// Exhaustively test up to 10 bits
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
index 35f0463e3e..edc41ec42c 100644
--- a/src/test/dbwrapper_tests.cpp
+++ b/src/test/dbwrapper_tests.cpp
@@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(iterator_ordering)
// Check that creating an iterator creates a snapshot
std::unique_ptr<CDBIterator> it(const_cast<CDBWrapper&>(dbw).NewIterator());
- for (int x=0x00; x<256; ++x) {
+ for (unsigned int x=0x00; x<256; ++x) {
uint8_t key = x;
uint32_t value = x*x;
if (x & 1) BOOST_CHECK(dbw.Write(key, value));
@@ -218,7 +218,7 @@ BOOST_AUTO_TEST_CASE(iterator_ordering)
for (int seek_start : {0x00, 0x80}) {
it->Seek((uint8_t)seek_start);
- for (int x=seek_start; x<255; ++x) {
+ for (unsigned int x=seek_start; x<255; ++x) {
uint8_t key;
uint32_t value;
BOOST_CHECK(it->Valid());
@@ -295,7 +295,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering)
snprintf(buf, sizeof(buf), "%d", seek_start);
StringContentsSerializer seek_key(buf);
it->Seek(seek_key);
- for (int x=seek_start; x<10; ++x) {
+ for (unsigned int x=seek_start; x<10; ++x) {
for (int y = 0; y < 10; y++) {
snprintf(buf, sizeof(buf), "%d", x);
std::string exp_key(buf);
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
index 0de0a17904..d7d6c9b5a3 100644
--- a/src/test/hash_tests.cpp
+++ b/src/test/hash_tests.cpp
@@ -25,22 +25,22 @@ BOOST_AUTO_TEST_CASE(murmurhash3)
//
// The magic number 0xFBA4C795 comes from CBloomFilter::Hash()
- T(0x00000000, 0x00000000, "");
- T(0x6a396f08, 0xFBA4C795, "");
- T(0x81f16f39, 0xffffffff, "");
-
- T(0x514e28b7, 0x00000000, "00");
- T(0xea3f0b17, 0xFBA4C795, "00");
- T(0xfd6cf10d, 0x00000000, "ff");
-
- T(0x16c6b7ab, 0x00000000, "0011");
- T(0x8eb51c3d, 0x00000000, "001122");
- T(0xb4471bf8, 0x00000000, "00112233");
- T(0xe2301fa8, 0x00000000, "0011223344");
- T(0xfc2e4a15, 0x00000000, "001122334455");
- T(0xb074502c, 0x00000000, "00112233445566");
- T(0x8034d2a0, 0x00000000, "0011223344556677");
- T(0xb4698def, 0x00000000, "001122334455667788");
+ T(0x00000000U, 0x00000000, "");
+ T(0x6a396f08U, 0xFBA4C795, "");
+ T(0x81f16f39U, 0xffffffff, "");
+
+ T(0x514e28b7U, 0x00000000, "00");
+ T(0xea3f0b17U, 0xFBA4C795, "00");
+ T(0xfd6cf10dU, 0x00000000, "ff");
+
+ T(0x16c6b7abU, 0x00000000, "0011");
+ T(0x8eb51c3dU, 0x00000000, "001122");
+ T(0xb4471bf8U, 0x00000000, "00112233");
+ T(0xe2301fa8U, 0x00000000, "0011223344");
+ T(0xfc2e4a15U, 0x00000000, "001122334455");
+ T(0xb074502cU, 0x00000000, "00112233445566");
+ T(0x8034d2a0U, 0x00000000, "0011223344556677");
+ T(0xb4698defU, 0x00000000, "001122334455667788");
#undef T
}
diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp
index a833a5cb1e..570c205731 100644
--- a/src/test/main_tests.cpp
+++ b/src/test/main_tests.cpp
@@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test)
nSum += nSubsidy * 1000;
BOOST_CHECK(MoneyRange(nSum));
}
- BOOST_CHECK_EQUAL(nSum, 2099999997690000ULL);
+ BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000});
}
bool ReturnFalse() { return false; }
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index 19cd3b0963..37615d08b3 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
poolSize = testPool.size();
testPool.removeRecursive(txParent);
BOOST_CHECK_EQUAL(testPool.size(), poolSize - 5);
- BOOST_CHECK_EQUAL(testPool.size(), 0);
+ BOOST_CHECK_EQUAL(testPool.size(), 0U);
// Add children and grandchildren, but NOT the parent (simulate the parent being in a block)
for (int i = 0; i < 3; i++)
@@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
poolSize = testPool.size();
testPool.removeRecursive(txParent);
BOOST_CHECK_EQUAL(testPool.size(), poolSize - 6);
- BOOST_CHECK_EQUAL(testPool.size(), 0);
+ BOOST_CHECK_EQUAL(testPool.size(), 0U);
}
template<typename name>
@@ -156,7 +156,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
tx5.vout[0].nValue = 11 * COIN;
entry.nTime = 1;
pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5));
- BOOST_CHECK_EQUAL(pool.size(), 5);
+ BOOST_CHECK_EQUAL(pool.size(), 5U);
std::vector<std::string> sortedOrder;
sortedOrder.resize(5);
@@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
tx6.vout[0].nValue = 20 * COIN;
pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6));
- BOOST_CHECK_EQUAL(pool.size(), 6);
+ BOOST_CHECK_EQUAL(pool.size(), 6U);
// Check that at this point, tx6 is sorted low
sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString());
CheckSort<descendant_score>(pool, sortedOrder);
@@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
BOOST_CHECK(setAncestorsCalculated == setAncestors);
pool.addUnchecked(tx7.GetHash(), entry.FromTx(tx7), setAncestors);
- BOOST_CHECK_EQUAL(pool.size(), 7);
+ BOOST_CHECK_EQUAL(pool.size(), 7U);
// Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ...
sortedOrder.erase(sortedOrder.begin());
@@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
pool.addUnchecked(tx9.GetHash(), entry.Fee(0LL).Time(3).FromTx(tx9), setAncestors);
// tx9 should be sorted low
- BOOST_CHECK_EQUAL(pool.size(), 9);
+ BOOST_CHECK_EQUAL(pool.size(), 9U);
sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString());
CheckSort<descendant_score>(pool, sortedOrder);
@@ -279,7 +279,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
CheckSort<descendant_score>(pool, sortedOrder);
// there should be 10 transactions in the mempool
- BOOST_CHECK_EQUAL(pool.size(), 10);
+ BOOST_CHECK_EQUAL(pool.size(), 10U);
// Now try removing tx10 and verify the sort order returns to normal
pool.removeRecursive(pool.mapTx.find(tx10.GetHash())->GetTx());
@@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
tx5.vout[0].nValue = 11 * COIN;
pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5));
- BOOST_CHECK_EQUAL(pool.size(), 5);
+ BOOST_CHECK_EQUAL(pool.size(), 5U);
std::vector<std::string> sortedOrder;
sortedOrder.resize(5);
@@ -359,7 +359,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
uint64_t tx6Size = GetVirtualTransactionSize(tx6);
pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6));
- BOOST_CHECK_EQUAL(pool.size(), 6);
+ BOOST_CHECK_EQUAL(pool.size(), 6U);
// Ties are broken by hash
if (tx3.GetHash() < tx6.GetHash())
sortedOrder.push_back(tx6.GetHash().ToString());
@@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1;
pool.addUnchecked(tx7.GetHash(), entry.Fee(fee).FromTx(tx7));
- BOOST_CHECK_EQUAL(pool.size(), 7);
+ BOOST_CHECK_EQUAL(pool.size(), 7U);
sortedOrder.insert(sortedOrder.begin()+1, tx7.GetHash().ToString());
CheckSort<ancestor_score>(pool, sortedOrder);
diff --git a/src/test/merkleblock_tests.cpp b/src/test/merkleblock_tests.cpp
index 37a1a84136..2472ea9950 100644
--- a/src/test/merkleblock_tests.cpp
+++ b/src/test/merkleblock_tests.cpp
@@ -35,20 +35,20 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_found)
BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex());
// vMatchedTxn is only used when bloom filter is specified.
- BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0);
+ BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U);
std::vector<uint256> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex());
- BOOST_CHECK_EQUAL(vMatched.size(), 2);
+ BOOST_CHECK_EQUAL(vMatched.size(), 2U);
// Ordered by occurrence in depth-first tree traversal.
BOOST_CHECK_EQUAL(vMatched[0].ToString(), txhash2.ToString());
- BOOST_CHECK_EQUAL(vIndex[0], 1);
+ BOOST_CHECK_EQUAL(vIndex[0], 1U);
BOOST_CHECK_EQUAL(vMatched[1].ToString(), txhash1.ToString());
- BOOST_CHECK_EQUAL(vIndex[1], 8);
+ BOOST_CHECK_EQUAL(vIndex[1], 8U);
}
@@ -65,14 +65,14 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_not_found)
CMerkleBlock merkleBlock(block, txids2);
BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex());
- BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0);
+ BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U);
std::vector<uint256> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex());
- BOOST_CHECK_EQUAL(vMatched.size(), 0);
- BOOST_CHECK_EQUAL(vIndex.size(), 0);
+ BOOST_CHECK_EQUAL(vMatched.size(), 0U);
+ BOOST_CHECK_EQUAL(vIndex.size(), 0U);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index d9f6772c2d..c98566f9ca 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -501,7 +501,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
// it into the template because we still check IsFinalTx in CreateNewBlock,
// but relative locked txs will if inconsistently added to mempool.
// For now these will still generate a valid template until BIP68 soft fork
- BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
+ BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3U);
// However if we advance height by 1 and time by 512, all of them should be mined
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
@@ -509,7 +509,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1);
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
- BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5);
+ BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U);
chainActive.Tip()->nHeight--;
SetMockTime(0);
diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp
index 26b2f5d0d7..9abfd5ebd8 100644
--- a/src/test/pow_tests.cpp
+++ b/src/test/pow_tests.cpp
@@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(get_next_work)
pindexLast.nHeight = 32255;
pindexLast.nTime = 1262152739; // Block #32255
pindexLast.nBits = 0x1d00ffff;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00d86a);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00d86aU);
}
/* Test the constraint on the upper bound for next work */
@@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
pindexLast.nHeight = 2015;
pindexLast.nTime = 1233061996; // Block #2015
pindexLast.nBits = 0x1d00ffff;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00ffff);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00ffffU);
}
/* Test the constraint on the lower bound for actual time taken */
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
pindexLast.nHeight = 68543;
pindexLast.nTime = 1279297671; // Block #68543
pindexLast.nBits = 0x1c05a3f4;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0168fd);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0168fdU);
}
/* Test the constraint on the upper bound for actual time taken */
@@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
pindexLast.nHeight = 46367;
pindexLast.nTime = 1269211443; // Block #46367
pindexLast.nBits = 0x1c387f6f;
- BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fd);
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fdU);
}
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp
index 623ed239f0..80a294d129 100644
--- a/src/test/random_tests.cpp
+++ b/src/test/random_tests.cpp
@@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(fastrandom_randbits)
for (int bits = 0; bits < 63; ++bits) {
for (int j = 0; j < 1000; ++j) {
uint64_t rangebits = ctx1.randbits(bits);
- BOOST_CHECK_EQUAL(rangebits >> bits, 0);
+ BOOST_CHECK_EQUAL(rangebits >> bits, 0U);
uint64_t range = ((uint64_t)1) << bits | rangebits;
uint64_t rand = ctx2.randrange(range);
BOOST_CHECK(rand < range);
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 8d9f80ada0..242e1fb7ff 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0 remove")));
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned")));
ar = r.get_array();
- BOOST_CHECK_EQUAL(ar.size(), 0);
+ BOOST_CHECK_EQUAL(ar.size(), 0U);
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/24 add 1607731200 true")));
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned")));
@@ -275,7 +275,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0/24 remove")));
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned")));
ar = r.get_array();
- BOOST_CHECK_EQUAL(ar.size(), 0);
+ BOOST_CHECK_EQUAL(ar.size(), 0U);
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/255.255.0.0 add")));
BOOST_CHECK_THROW(r = CallRPC(std::string("setban 127.0.1.1 add")), std::runtime_error);
@@ -283,7 +283,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned")));
BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned")));
ar = r.get_array();
- BOOST_CHECK_EQUAL(ar.size(), 0);
+ BOOST_CHECK_EQUAL(ar.size(), 0U);
BOOST_CHECK_THROW(r = CallRPC(std::string("setban test add")), std::runtime_error); //invalid IP
diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp
index cd30fbeda7..767c5fdbd2 100644
--- a/src/test/script_standard_tests.cpp
+++ b/src/test/script_standard_tests.cpp
@@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_PUBKEY);
- BOOST_CHECK_EQUAL(solutions.size(), 1);
+ BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
// TX_PUBKEYHASH
@@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH);
- BOOST_CHECK_EQUAL(solutions.size(), 1);
+ BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
// TX_SCRIPTHASH
@@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH);
- BOOST_CHECK_EQUAL(solutions.size(), 1);
+ BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
// TX_MULTISIG
@@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_MULTISIG);
- BOOST_CHECK_EQUAL(solutions.size(), 4);
+ BOOST_CHECK_EQUAL(solutions.size(), 4U);
BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
@@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
OP_3 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_MULTISIG);
- BOOST_CHECK_EQUAL(solutions.size(), 5);
+ BOOST_CHECK_EQUAL(solutions.size(), 5U);
BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
@@ -90,14 +90,14 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
std::vector<unsigned char>({255});
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_NULL_DATA);
- BOOST_CHECK_EQUAL(solutions.size(), 0);
+ BOOST_CHECK_EQUAL(solutions.size(), 0U);
// TX_WITNESS_V0_KEYHASH
s.clear();
s << OP_0 << ToByteVector(pubkeys[0].GetID());
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_WITNESS_V0_KEYHASH);
- BOOST_CHECK_EQUAL(solutions.size(), 1);
+ BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
// TX_WITNESS_V0_SCRIPTHASH
@@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
s << OP_0 << ToByteVector(scriptHash);
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(whichType, TX_WITNESS_V0_SCRIPTHASH);
- BOOST_CHECK_EQUAL(solutions.size(), 1);
+ BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));
// TX_NONSTANDARD
@@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_PUBKEY);
- BOOST_CHECK_EQUAL(addresses.size(), 1);
+ BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) &&
*boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID());
@@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH);
- BOOST_CHECK_EQUAL(addresses.size(), 1);
+ BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) &&
*boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID());
@@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH);
- BOOST_CHECK_EQUAL(addresses.size(), 1);
+ BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<CScriptID>(&addresses[0]) &&
*boost::get<CScriptID>(&addresses[0]) == CScriptID(redeemScript));
@@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_MULTISIG);
- BOOST_CHECK_EQUAL(addresses.size(), 2);
+ BOOST_CHECK_EQUAL(addresses.size(), 2U);
BOOST_CHECK_EQUAL(nRequired, 2);
BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) &&
*boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID());
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index 9b8b7bdc56..94164346f3 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -78,18 +78,18 @@ BOOST_AUTO_TEST_CASE(sizes)
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0));
// Sanity-check GetSerializeSize and c++ type matching
- BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1);
- BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1);
- BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1);
- BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2);
- BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2);
- BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4);
- BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4);
- BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8);
- BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8);
- BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4);
- BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8);
- BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8U);
+ BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1U);
}
BOOST_AUTO_TEST_CASE(floats_conversion)
@@ -103,12 +103,12 @@ BOOST_AUTO_TEST_CASE(floats_conversion)
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F);
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F);
- BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000);
- BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000);
- BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000);
- BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000);
- BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000);
- BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000U);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000U);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000U);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000U);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000U);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444U);
}
BOOST_AUTO_TEST_CASE(doubles_conversion)
@@ -299,39 +299,39 @@ BOOST_AUTO_TEST_CASE(insert_delete)
{
// Test inserting/deleting bytes.
CDataStream ss(SER_DISK, 0);
- BOOST_CHECK_EQUAL(ss.size(), 0);
+ BOOST_CHECK_EQUAL(ss.size(), 0U);
ss.write("\x00\x01\x02\xff", 4);
- BOOST_CHECK_EQUAL(ss.size(), 4);
+ BOOST_CHECK_EQUAL(ss.size(), 4U);
char c = (char)11;
// Inserting at beginning/end/middle:
ss.insert(ss.begin(), c);
- BOOST_CHECK_EQUAL(ss.size(), 5);
+ BOOST_CHECK_EQUAL(ss.size(), 5U);
BOOST_CHECK_EQUAL(ss[0], c);
BOOST_CHECK_EQUAL(ss[1], 0);
ss.insert(ss.end(), c);
- BOOST_CHECK_EQUAL(ss.size(), 6);
+ BOOST_CHECK_EQUAL(ss.size(), 6U);
BOOST_CHECK_EQUAL(ss[4], (char)0xff);
BOOST_CHECK_EQUAL(ss[5], c);
ss.insert(ss.begin()+2, c);
- BOOST_CHECK_EQUAL(ss.size(), 7);
+ BOOST_CHECK_EQUAL(ss.size(), 7U);
BOOST_CHECK_EQUAL(ss[2], c);
// Delete at beginning/end/middle
ss.erase(ss.begin());
- BOOST_CHECK_EQUAL(ss.size(), 6);
+ BOOST_CHECK_EQUAL(ss.size(), 6U);
BOOST_CHECK_EQUAL(ss[0], 0);
ss.erase(ss.begin()+ss.size()-1);
- BOOST_CHECK_EQUAL(ss.size(), 5);
+ BOOST_CHECK_EQUAL(ss.size(), 5U);
BOOST_CHECK_EQUAL(ss[4], (char)0xff);
ss.erase(ss.begin()+1);
- BOOST_CHECK_EQUAL(ss.size(), 4);
+ BOOST_CHECK_EQUAL(ss.size(), 4U);
BOOST_CHECK_EQUAL(ss[0], 0);
BOOST_CHECK_EQUAL(ss[1], 1);
BOOST_CHECK_EQUAL(ss[2], 2);
@@ -340,7 +340,7 @@ BOOST_AUTO_TEST_CASE(insert_delete)
// Make sure GetAndClear does the right thing:
CSerializeData d;
ss.GetAndClear(d);
- BOOST_CHECK_EQUAL(ss.size(), 0);
+ BOOST_CHECK_EQUAL(ss.size(), 0U);
}
BOOST_AUTO_TEST_CASE(class_methods)
diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp
index d0aa8659c2..9ece9e70c2 100644
--- a/src/test/torcontrol_tests.cpp
+++ b/src/test/torcontrol_tests.cpp
@@ -167,10 +167,10 @@ BOOST_AUTO_TEST_CASE(util_ParseTorReplyMapping)
// (needed because string comparison reads the null as end-of-string)
BOOST_TEST_MESSAGE(std::string("CheckParseTorReplyMapping(Null=\"\\0\")"));
auto ret = ParseTorReplyMapping("Null=\"\\0\"");
- BOOST_CHECK_EQUAL(ret.size(), 1);
+ BOOST_CHECK_EQUAL(ret.size(), 1U);
auto r_it = ret.begin();
BOOST_CHECK_EQUAL(r_it->first, "Null");
- BOOST_CHECK_EQUAL(r_it->second.size(), 1);
+ BOOST_CHECK_EQUAL(r_it->second.size(), 1U);
BOOST_CHECK_EQUAL(r_it->second[0], '\0');
// A more complex valid grammar. PROTOCOLINFO accepts a VersionLine that
diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp
index 7087c26774..71f3d727b1 100644
--- a/src/test/txvalidationcache_tests.cpp
+++ b/src/test/txvalidationcache_tests.cpp
@@ -88,7 +88,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash());
// spends[1] should have been removed from the mempool when the
// block with spends[0] is accepted:
- BOOST_CHECK_EQUAL(mempool.size(), 0);
+ BOOST_CHECK_EQUAL(mempool.size(), 0U);
}
// Run CheckInputs (using pcoinsTip) on the given transaction, for all script
@@ -205,7 +205,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// not caching invalidity (if that changes, delete this test case).
std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
- BOOST_CHECK_EQUAL(scriptchecks.size(), 1);
+ BOOST_CHECK_EQUAL(scriptchecks.size(), 1U);
// Test that CheckInputs returns true iff DERSIG-enforcing flags are
// not present. Don't add these checks to the cache, so that we can
@@ -314,7 +314,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign
SignatureData sigdata;
- ProduceSignature(MutableTransactionSignatureCreator(&keystore, &valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata);
+ ProduceSignature(keystore, MutableTransactionSignatureCreator(&valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata);
UpdateTransaction(valid_with_witness_tx, 0, sigdata);
// This should be valid under all script flags.
@@ -342,7 +342,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign
for (int i=0; i<2; ++i) {
SignatureData sigdata;
- ProduceSignature(MutableTransactionSignatureCreator(&keystore, &tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata);
+ ProduceSignature(keystore, MutableTransactionSignatureCreator(&tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata);
UpdateTransaction(tx, i, sigdata);
}
@@ -364,7 +364,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// input was valid)
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
// Should get 2 script checks back -- caching is on a whole-transaction basis.
- BOOST_CHECK_EQUAL(scriptchecks.size(), 2);
+ BOOST_CHECK_EQUAL(scriptchecks.size(), 2U);
}
}
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index fa49d6d7ff..344113b60c 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -159,17 +159,6 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
}
-BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
-{
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", 1317425777), "2011-09-30T23:36:17Z");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%H:%M:%SZ", 1317425777), "23:36:17Z");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000");
-}
-
BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime)
{
BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
diff --git a/src/util.h b/src/util.h
index ba80c21ddc..ffdee99d27 100644
--- a/src/util.h
+++ b/src/util.h
@@ -146,14 +146,16 @@ template<typename T, typename... Args> static inline void MarkUsed(const T& t, c
#define LogPrint(category, ...) do { MarkUsed(__VA_ARGS__); } while(0)
#else
#define LogPrintf(...) do { \
- std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \
- try { \
- _log_msg_ = tfm::format(__VA_ARGS__); \
- } catch (tinyformat::format_error &fmterr) { \
- /* Original format string will have newline so don't add one here */ \
- _log_msg_ = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(__VA_ARGS__); \
+ if (fPrintToConsole || fPrintToDebugLog) { \
+ std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \
+ try { \
+ _log_msg_ = tfm::format(__VA_ARGS__); \
+ } catch (tinyformat::format_error &fmterr) { \
+ /* Original format string will have newline so don't add one here */ \
+ _log_msg_ = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(__VA_ARGS__); \
+ } \
+ LogPrintStr(_log_msg_); \
} \
- LogPrintStr(_log_msg_); \
} while(0)
#define LogPrint(category, ...) do { \
diff --git a/src/utiltime.cpp b/src/utiltime.cpp
index 8a861039b3..34800c7b6d 100644
--- a/src/utiltime.cpp
+++ b/src/utiltime.cpp
@@ -10,9 +10,10 @@
#include <utiltime.h>
#include <atomic>
-
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread.hpp>
+#include <ctime>
+#include <tinyformat.h>
static std::atomic<int64_t> nMockTime(0); //!< For unit testing
@@ -75,25 +76,23 @@ void MilliSleep(int64_t n)
#endif
}
-std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
-{
- static std::locale classic(std::locale::classic());
- // std::locale takes ownership of the pointer
- std::locale loc(classic, new boost::posix_time::time_facet(pszFormat));
- std::stringstream ss;
- ss.imbue(loc);
- ss << boost::posix_time::from_time_t(nTime);
- return ss.str();
-}
-
std::string FormatISO8601DateTime(int64_t nTime) {
- return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
+ struct tm ts;
+ time_t time_val = nTime;
+ gmtime_r(&time_val, &ts);
+ return strprintf("%04i-%02i-%02iT%02i:%02i:%02iZ", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec);
}
std::string FormatISO8601Date(int64_t nTime) {
- return DateTimeStrFormat("%Y-%m-%d", nTime);
+ struct tm ts;
+ time_t time_val = nTime;
+ gmtime_r(&time_val, &ts);
+ return strprintf("%04i-%02i-%02i", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday);
}
std::string FormatISO8601Time(int64_t nTime) {
- return DateTimeStrFormat("%H:%M:%SZ", nTime);
+ struct tm ts;
+ time_t time_val = nTime;
+ gmtime_r(&time_val, &ts);
+ return strprintf("%02i:%02i:%02iZ", ts.tm_hour, ts.tm_min, ts.tm_sec);
}
diff --git a/src/utiltime.h b/src/utiltime.h
index 807c52ffaf..3bcbb00c16 100644
--- a/src/utiltime.h
+++ b/src/utiltime.h
@@ -31,8 +31,6 @@ void MilliSleep(int64_t n);
* ISO 8601 formatting is preferred. Use the FormatISO8601{DateTime,Date,Time}
* helper functions if possible.
*/
-std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime);
-
std::string FormatISO8601DateTime(int64_t nTime);
std::string FormatISO8601Date(int64_t nTime);
std::string FormatISO8601Time(int64_t nTime);
diff --git a/src/validation.cpp b/src/validation.cpp
index 4a6c4066fc..958c187220 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -202,8 +202,9 @@ CCriticalSection cs_main;
BlockMap& mapBlockIndex = g_chainstate.mapBlockIndex;
CChain& chainActive = g_chainstate.chainActive;
CBlockIndex *pindexBestHeader = nullptr;
-CWaitableCriticalSection csBestBlock;
-CConditionVariable cvBlockChange;
+CWaitableCriticalSection g_best_block_mutex;
+CConditionVariable g_best_block_cv;
+uint256 g_best_block;
int nScriptCheckThreads = 0;
std::atomic_bool fImporting(false);
std::atomic_bool fReindex(false);
@@ -263,7 +264,8 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc
{
AssertLockHeld(cs_main);
- // Find the first block the caller has in the main chain
+ // Find the latest block common to locator and chain - we expect that
+ // locator.vHave is sorted descending by height.
for (const uint256& hash : locator.vHave) {
CBlockIndex* pindex = LookupBlockIndex(hash);
if (pindex) {
@@ -2064,6 +2066,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
* The caches and indexes are flushed depending on the mode we're called with
* if they're too large, if it's been a while since the last write,
* or always and in all cases if we're in prune mode and are deleting files.
+ *
+ * If FlushStateMode::NONE is used, then FlushStateToDisk(...) won't do anything
+ * besides checking if we need to prune.
*/
bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight) {
int64_t nMempoolUsage = mempool.DynamicMemoryUsage();
@@ -2201,7 +2206,11 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
// New best block
mempool.AddTransactionsUpdated(1);
- cvBlockChange.notify_all();
+ {
+ WaitableLock lock(g_best_block_mutex);
+ g_best_block = pindexNew->GetBlockHash();
+ g_best_block_cv.notify_all();
+ }
std::vector<std::string> warningMessages;
if (!IsInitialBlockDownload())
@@ -3454,8 +3463,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CVali
return AbortNode(state, std::string("System error: ") + e.what());
}
- if (fCheckForPruning)
- FlushStateToDisk(chainparams, state, FlushStateMode::NONE); // we just allocated more disk space for block files
+ FlushStateToDisk(chainparams, state, FlushStateMode::NONE);
CheckBlockIndex(chainparams.GetConsensus());
diff --git a/src/validation.h b/src/validation.h
index dad6858b1e..3668484696 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -165,8 +165,9 @@ extern BlockMap& mapBlockIndex;
extern uint64_t nLastBlockTx;
extern uint64_t nLastBlockWeight;
extern const std::string strMessageMagic;
-extern CWaitableCriticalSection csBestBlock;
-extern CConditionVariable cvBlockChange;
+extern CWaitableCriticalSection g_best_block_mutex;
+extern CConditionVariable g_best_block_cv;
+extern uint256 g_best_block;
extern std::atomic_bool fImporting;
extern std::atomic_bool fReindex;
extern int nScriptCheckThreads;
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index a3594aa692..b8533839a0 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -172,7 +172,13 @@ UniValue importprivkey(const JSONRPCRequest& request)
}
}
if (fRescan) {
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
}
return NullUniValue;
@@ -310,7 +316,13 @@ UniValue importaddress(const JSONRPCRequest& request)
}
if (fRescan)
{
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->ReacceptWalletTransactions();
}
@@ -479,7 +491,13 @@ UniValue importpubkey(const JSONRPCRequest& request)
}
if (fRescan)
{
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->ReacceptWalletTransactions();
}
@@ -534,9 +552,11 @@ UniValue importwallet(const JSONRPCRequest& request)
int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
file.seekg(0, file.beg);
- pwallet->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI
+ // Use uiInterface.ShowProgress instead of pwallet.ShowProgress because pwallet.ShowProgress has a cancel button tied to AbortRescan which
+ // we don't want for this progress bar shoing the import progress. uiInterface.ShowProgress does not have a cancel button.
+ uiInterface.ShowProgress(_("Importing..."), 0, false); // show progress dialog in GUI
while (file.good()) {
- pwallet->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))));
+ uiInterface.ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))), false);
std::string line;
std::getline(file, line);
if (line.empty() || line[0] == '#')
@@ -599,10 +619,17 @@ UniValue importwallet(const JSONRPCRequest& request)
}
}
file.close();
- pwallet->ShowProgress("", 100); // hide progress dialog in GUI
+ uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
pwallet->UpdateTimeFirstKey(nTimeBegin);
}
- pwallet->RescanFromTime(nTimeBegin, reserver, false /* update */);
+ uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
+ int64_t scanned_time = pwallet->RescanFromTime(nTimeBegin, reserver, false /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > nTimeBegin) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->MarkDirty();
if (!fGood)
@@ -1212,6 +1239,9 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, reserver, true /* update */);
pwallet->ReacceptWalletTransactions();
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
if (scannedTime > nLowestTimestamp) {
std::vector<UniValue> results = response.getValues();
response.clear();
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 29760a7092..56bdc0695c 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -189,7 +189,6 @@ UniValue getnewaddress(const JSONRPCRequest& request)
return EncodeDestination(dest);
}
-
CTxDestination GetLabelDestination(CWallet* const pwallet, const std::string& label, bool bForceNew=false)
{
CTxDestination dest;
@@ -207,14 +206,16 @@ UniValue getlabeladdress(const JSONRPCRequest& request)
return NullUniValue;
}
- if (request.fHelp || request.params.size() != 1)
+ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
- "getlabeladdress \"label\"\n"
- "\nReturns the current Bitcoin address for receiving payments to this label.\n"
+ "getlabeladdress \"label\" ( force ) \n"
+ "\nReturns the default receiving address for this label. This will reset to a fresh address once there's a transaction that spends to it.\n"
"\nArguments:\n"
- "1. \"label\" (string, required) The label name for the address. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created and a new address created if there is no label by the given name.\n"
+ "1. \"label\" (string, required) The label for the address. It can also be set to the empty string \"\" to represent the default label.\n"
+ "2. \"force\" (bool, optional) Whether the label should be created if it does not yet exist. If False, the RPC will return an error if called with a label that doesn't exist.\n"
+ " Defaults to false (unless the getaccountaddress method alias is being called, in which case defaults to true for backwards compatibility).\n"
"\nResult:\n"
- "\"address\" (string) The label bitcoin address\n"
+ "\"address\" (string) The current receiving address for the label.\n"
"\nExamples:\n"
+ HelpExampleCli("getlabeladdress", "")
+ HelpExampleCli("getlabeladdress", "\"\"")
@@ -226,6 +227,21 @@ UniValue getlabeladdress(const JSONRPCRequest& request)
// Parse the label first so we don't generate a key if there's an error
std::string label = LabelFromValue(request.params[0]);
+ bool force = request.strMethod == "getaccountaddress" ? true : false;
+ if (!request.params[1].isNull()) {
+ force = request.params[1].get_bool();
+ }
+
+ bool label_found = false;
+ for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
+ if (item.second.name == label) {
+ label_found = true;
+ break;
+ }
+ }
+ if (!force && !label_found) {
+ throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, std::string("No addresses with label " + label));
+ }
UniValue ret(UniValue::VSTR);
@@ -290,13 +306,13 @@ UniValue setlabel(const JSONRPCRequest& request)
return NullUniValue;
}
- if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
+ if (request.fHelp || request.params.size() != 2)
throw std::runtime_error(
"setlabel \"address\" \"label\"\n"
"\nSets the label associated with the given address.\n"
"\nArguments:\n"
"1. \"address\" (string, required) The bitcoin address to be associated with a label.\n"
- "2. \"label\" (string, required) The label to assign the address to.\n"
+ "2. \"label\" (string, required) The label to assign to the address.\n"
"\nExamples:\n"
+ HelpExampleCli("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"")
+ HelpExampleRpc("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"")
@@ -309,23 +325,22 @@ UniValue setlabel(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
}
- std::string label;
- if (!request.params[1].isNull())
- label = LabelFromValue(request.params[1]);
+ std::string label = LabelFromValue(request.params[1]);
- // Only add the label if the address is yours.
if (IsMine(*pwallet, dest)) {
- // Detect when changing the label of an address that is the 'unused current key' of another label:
+ // Detect when changing the label of an address that is the receiving address of another label:
+ // If so, delete the account record for it. Labels, unlike addresses, can be deleted,
+ // and if we wouldn't do this, the record would stick around forever.
if (pwallet->mapAddressBook.count(dest)) {
std::string old_label = pwallet->mapAddressBook[dest].name;
- if (dest == GetLabelDestination(pwallet, old_label)) {
- GetLabelDestination(pwallet, old_label, true);
+ if (old_label != label && dest == GetLabelDestination(pwallet, old_label)) {
+ pwallet->DeleteLabel(old_label);
}
}
pwallet->SetAddressBook(dest, label, "receive");
+ } else {
+ pwallet->SetAddressBook(dest, label, "send");
}
- else
- throw JSONRPCError(RPC_MISC_ERROR, "setlabel can only be used with own address");
return NullUniValue;
}
@@ -1562,7 +1577,7 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
" \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
" \"label\" : \"label\", (string) The label of the receiving address. The default label is \"\".\n"
" \"txids\": [\n"
- " n, (numeric) The ids of transactions received with the address \n"
+ " \"txid\", (string) The ids of transactions received with the address \n"
" ...\n"
" ]\n"
" }\n"
@@ -3720,6 +3735,17 @@ UniValue DescribeWalletAddress(CWallet* pwallet, const CTxDestination& dest)
return ret;
}
+/** Convert CAddressBookData to JSON record. */
+static UniValue AddressBookDataToJSON(const CAddressBookData& data, const bool verbose)
+{
+ UniValue ret(UniValue::VOBJ);
+ if (verbose) {
+ ret.pushKV("name", data.name);
+ }
+ ret.pushKV("purpose", data.purpose);
+ return ret;
+}
+
UniValue getaddressinfo(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
@@ -3759,6 +3785,13 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
" \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
" \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
" \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
+ " \"labels\" (object) Array of labels associated with the address.\n"
+ " [\n"
+ " { (json object of label data)\n"
+ " \"name\": \"labelname\" (string) The label\n"
+ " \"purpose\": \"string\" (string) Purpose of address (\"send\" for sending address, \"receive\" for receiving address)\n"
+ " },...\n"
+ " ]\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
@@ -3811,6 +3844,112 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex());
}
}
+
+ // Currently only one label can be associated with an address, return an array
+ // so the API remains stable if we allow multiple labels to be associated with
+ // an address.
+ UniValue labels(UniValue::VARR);
+ std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(dest);
+ if (mi != pwallet->mapAddressBook.end()) {
+ labels.push_back(AddressBookDataToJSON(mi->second, true));
+ }
+ ret.pushKV("labels", std::move(labels));
+
+ return ret;
+}
+
+UniValue getaddressesbylabel(const JSONRPCRequest& request)
+{
+ CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
+ return NullUniValue;
+ }
+
+ if (request.fHelp || request.params.size() != 1)
+ throw std::runtime_error(
+ "getaddressesbylabel \"label\"\n"
+ "\nReturns the list of addresses assigned the specified label.\n"
+ "\nArguments:\n"
+ "1. \"label\" (string, required) The label.\n"
+ "\nResult:\n"
+ "{ (json object with addresses as keys)\n"
+ " \"address\": { (json object with information about address)\n"
+ " \"purpose\": \"string\" (string) Purpose of address (\"send\" for sending address, \"receive\" for receiving address)\n"
+ " },...\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getaddressesbylabel", "\"tabby\"")
+ + HelpExampleRpc("getaddressesbylabel", "\"tabby\"")
+ );
+
+ LOCK(pwallet->cs_wallet);
+
+ std::string label = LabelFromValue(request.params[0]);
+
+ // Find all addresses that have the given label
+ UniValue ret(UniValue::VOBJ);
+ for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
+ if (item.second.name == label) {
+ ret.pushKV(EncodeDestination(item.first), AddressBookDataToJSON(item.second, false));
+ }
+ }
+
+ if (ret.empty()) {
+ throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, std::string("No addresses with label " + label));
+ }
+
+ return ret;
+}
+
+UniValue listlabels(const JSONRPCRequest& request)
+{
+ CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
+ return NullUniValue;
+ }
+
+ if (request.fHelp || request.params.size() > 1)
+ throw std::runtime_error(
+ "listlabels ( \"purpose\" )\n"
+ "\nReturns the list of all labels, or labels that are assigned to addresses with a specific purpose.\n"
+ "\nArguments:\n"
+ "1. \"purpose\" (string, optional) Address purpose to list labels for ('send','receive'). An empty string is the same as not providing this argument.\n"
+ "\nResult:\n"
+ "[ (json array of string)\n"
+ " \"label\", (string) Label name\n"
+ " ...\n"
+ "]\n"
+ "\nExamples:\n"
+ "\nList all labels\n"
+ + HelpExampleCli("listlabels", "") +
+ "\nList labels that have receiving addresses\n"
+ + HelpExampleCli("listlabels", "receive") +
+ "\nList labels that have sending addresses\n"
+ + HelpExampleCli("listlabels", "send") +
+ "\nAs json rpc call\n"
+ + HelpExampleRpc("listlabels", "receive")
+ );
+
+ LOCK(pwallet->cs_wallet);
+
+ std::string purpose;
+ if (!request.params[0].isNull()) {
+ purpose = request.params[0].get_str();
+ }
+
+ // Add to a set to sort by label name, then insert into Univalue array
+ std::set<std::string> label_set;
+ for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) {
+ if (purpose.empty() || entry.second.purpose == purpose) {
+ label_set.insert(entry.second.name);
+ }
+ }
+
+ UniValue ret(UniValue::VARR);
+ for (const std::string& name : label_set) {
+ ret.push_back(name);
+ }
+
return ret;
}
@@ -3840,16 +3979,10 @@ static const CRPCCommand commands[] =
{ "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
{ "wallet", "dumpwallet", &dumpwallet, {"filename"} },
{ "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
- { "wallet", "getlabeladdress", &getlabeladdress, {"label"} },
- { "wallet", "getaccountaddress", &getlabeladdress, {"account"} },
- { "wallet", "getaccount", &getaccount, {"address"} },
- { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
{ "wallet", "getaddressinfo", &getaddressinfo, {"address"} },
{ "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
{ "wallet", "getnewaddress", &getnewaddress, {"label|account","address_type"} },
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} },
- { "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf"} },
- { "wallet", "getreceivedbyaccount", &getreceivedbylabel, {"account","minconf"} },
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
{ "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
@@ -3861,7 +3994,6 @@ static const CRPCCommand commands[] =
{ "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
{ "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
{ "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
- { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
{ "wallet", "listaddressgroupings", &listaddressgroupings, {} },
{ "wallet", "listlockunspent", &listlockunspent, {} },
{ "wallet", "listreceivedbylabel", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} },
@@ -3872,12 +4004,9 @@ static const CRPCCommand commands[] =
{ "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
{ "wallet", "listwallets", &listwallets, {} },
{ "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
- { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
{ "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
{ "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
{ "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
- { "wallet", "setlabel", &setlabel, {"address","label"} },
- { "wallet", "setaccount", &setlabel, {"address","account"} },
{ "wallet", "settxfee", &settxfee, {"amount"} },
{ "wallet", "signmessage", &signmessage, {"address","message"} },
{ "wallet", "signrawtransactionwithwallet", &signrawtransactionwithwallet, {"hexstring","prevtxs","sighashtype"} },
@@ -3887,6 +4016,24 @@ static const CRPCCommand commands[] =
{ "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
{ "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} },
+ /** Account functions (deprecated) */
+ { "wallet", "getaccountaddress", &getlabeladdress, {"account"} },
+ { "wallet", "getaccount", &getaccount, {"address"} },
+ { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
+ { "wallet", "getreceivedbyaccount", &getreceivedbylabel, {"account","minconf"} },
+ { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
+ { "wallet", "listreceivedbyaccount", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} },
+ { "wallet", "setaccount", &setlabel, {"address","account"} },
+ { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
+
+ /** Label functions (to replace non-balance account functions) */
+ { "wallet", "getlabeladdress", &getlabeladdress, {"label","force"} },
+ { "wallet", "getaddressesbylabel", &getaddressesbylabel, {"label"} },
+ { "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf"} },
+ { "wallet", "listlabels", &listlabels, {"purpose"} },
+ { "wallet", "listreceivedbylabel", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} },
+ { "wallet", "setlabel", &setlabel, {"address","label"} },
+
{ "generating", "generate", &generate, {"nblocks","maxtries"} },
};
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 727c6caf96..14c5ad7214 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -156,8 +156,8 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
::importwallet(request);
LOCK(wallet.cs_wallet);
- BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3);
- BOOST_CHECK_EQUAL(coinbaseTxns.size(), 103);
+ BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U);
+ BOOST_CHECK_EQUAL(coinbaseTxns.size(), 103U);
for (size_t i = 0; i < coinbaseTxns.size(); ++i) {
bool found = wallet.GetWalletTx(coinbaseTxns[i].GetHash());
bool expected = i >= 100;
@@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(LoadReceiveRequests)
m_wallet.AddDestData(dest, "rr1", "val_rr1");
auto values = m_wallet.GetDestValues("rr");
- BOOST_CHECK_EQUAL(values.size(), 2);
+ BOOST_CHECK_EQUAL(values.size(), 2U);
BOOST_CHECK_EQUAL(values[0], "val_rr0");
BOOST_CHECK_EQUAL(values[1], "val_rr1");
}
@@ -318,9 +318,9 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
// Confirm ListCoins initially returns 1 coin grouped under coinbaseKey
// address.
auto list = wallet->ListCoins();
- BOOST_CHECK_EQUAL(list.size(), 1);
+ BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
- BOOST_CHECK_EQUAL(list.begin()->second.size(), 1);
+ BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U);
// Check initial balance from one mature coinbase transaction.
BOOST_CHECK_EQUAL(50 * COIN, wallet->GetAvailableBalance());
@@ -331,16 +331,16 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
// pubkey.
AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, false /* subtract fee */});
list = wallet->ListCoins();
- BOOST_CHECK_EQUAL(list.size(), 1);
+ BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
- BOOST_CHECK_EQUAL(list.begin()->second.size(), 2);
+ BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
// Lock both coins. Confirm number of available coins drops to 0.
{
LOCK2(cs_main, wallet->cs_wallet);
std::vector<COutput> available;
wallet->AvailableCoins(available);
- BOOST_CHECK_EQUAL(available.size(), 2);
+ BOOST_CHECK_EQUAL(available.size(), 2U);
}
for (const auto& group : list) {
for (const auto& coin : group.second) {
@@ -352,14 +352,14 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
LOCK2(cs_main, wallet->cs_wallet);
std::vector<COutput> available;
wallet->AvailableCoins(available);
- BOOST_CHECK_EQUAL(available.size(), 0);
+ BOOST_CHECK_EQUAL(available.size(), 0U);
}
// Confirm ListCoins still returns same result as before, despite coins
// being locked.
list = wallet->ListCoins();
- BOOST_CHECK_EQUAL(list.size(), 1);
+ BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
- BOOST_CHECK_EQUAL(list.begin()->second.size(), 2);
+ BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 4308b6d0e8..45c85a7912 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1535,7 +1535,7 @@ bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const
const CScript& scriptPubKey = txout.scriptPubKey;
SignatureData sigdata;
- if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))
+ if (!ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata))
{
return false;
} else {
@@ -1714,6 +1714,9 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
CBlockIndex* pindex = pindexStart;
CBlockIndex* ret = nullptr;
+
+ if (pindex) LogPrintf("Rescan started from block %d...\n", pindex->nHeight);
+
{
fAbortRescan = false;
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
@@ -2579,7 +2582,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
SignatureData sigdata;
- if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
+ if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
return false;
}
UpdateTransaction(tx, nIn, sigdata);
@@ -3008,7 +3011,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
const CScript& scriptPubKey = coin.txout.scriptPubKey;
SignatureData sigdata;
- if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
+ if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
{
strFailReason = _("Signing transaction failed");
return false;
@@ -3640,6 +3643,12 @@ std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) co
return result;
}
+void CWallet::DeleteLabel(const std::string& label)
+{
+ WalletBatch batch(*database);
+ batch.EraseAccount(label);
+}
+
bool CReserveKey::GetReservedKey(CPubKey& pubkey, bool internal)
{
if (nIndex == -1)
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index d66e3e481d..b85f374a06 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -549,7 +549,7 @@ public:
};
/**
- * Internal transfers.
+ * DEPRECATED Internal transfers.
* Database key is acentry<account><counter>.
*/
class CAccountingEntry
@@ -989,6 +989,7 @@ public:
std::map<CTxDestination, CAmount> GetAddressBalances();
std::set<CTxDestination> GetLabelAddresses(const std::string& label) const;
+ void DeleteLabel(const std::string& label);
isminetype IsMine(const CTxIn& txin) const;
/**
@@ -1184,7 +1185,7 @@ public:
/**
- * Account information.
+ * DEPRECATED Account information.
* Stored in wallet with key "acc"+string account name.
*/
class CAccount
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 57261bb922..bcc7cf877d 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -161,6 +161,11 @@ bool WalletBatch::WriteAccount(const std::string& strAccount, const CAccount& ac
return WriteIC(std::make_pair(std::string("acc"), strAccount), account);
}
+bool WalletBatch::EraseAccount(const std::string& strAccount)
+{
+ return EraseIC(std::make_pair(std::string("acc"), strAccount));
+}
+
bool WalletBatch::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry)
{
return WriteIC(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry);
@@ -227,13 +232,14 @@ public:
unsigned int nCKeys;
unsigned int nWatchKeys;
unsigned int nKeyMeta;
+ unsigned int m_unknown_records;
bool fIsEncrypted;
bool fAnyUnordered;
int nFileVersion;
std::vector<uint256> vWalletUpgrade;
CWalletScanState() {
- nKeys = nCKeys = nWatchKeys = nKeyMeta = 0;
+ nKeys = nCKeys = nWatchKeys = nKeyMeta = m_unknown_records = 0;
fIsEncrypted = false;
fAnyUnordered = false;
nFileVersion = 0;
@@ -504,6 +510,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
strErr = "Error reading wallet database: SetHDChain failed";
return false;
}
+ } else if (strType != "bestblock" && strType != "bestblock_nomerkle"){
+ wss.m_unknown_records++;
}
} catch (...)
{
@@ -595,8 +603,8 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
LogPrintf("nFileVersion = %d\n", wss.nFileVersion);
- LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
- wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys);
+ LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total. Unknown wallet records: %u\n",
+ wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys, wss.m_unknown_records);
// nTimeFirstKey is only reliable if all keys have metadata
if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta)
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index 040aa092e1..a73d727c0c 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -204,6 +204,7 @@ public:
bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry);
bool ReadAccount(const std::string& strAccount, CAccount& account);
bool WriteAccount(const std::string& strAccount, const CAccount& account);
+ bool EraseAccount(const std::string& strAccount);
/// Write destination data key,value tuple to database
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);