diff options
Diffstat (limited to 'src')
50 files changed, 536 insertions, 307 deletions
diff --git a/src/addrman.h b/src/addrman.h index 6dec3fe416..a36f7ea100 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -59,7 +59,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*static_cast<CAddress*>(this)); + READWRITEAS(CAddress, *this); READWRITE(source); READWRITE(nLastSuccess); READWRITE(nAttempts); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 36376d824e..07ad09ea7b 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -642,7 +642,7 @@ 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: sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i)); 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 9edd93000f..486c84f5a3 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/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/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/primitives/block.h b/src/primitives/block.h index 5d6d44ac76..1fca55d910 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -93,7 +93,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*static_cast<CBlockHeader*>(this)); + READWRITEAS(CBlockHeader, *this); READWRITE(vtx); } diff --git a/src/protocol.h b/src/protocol.h index a07c5ea862..3a9b2d2561 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -349,7 +349,7 @@ public: uint64_t nServicesInt = nServices; READWRITE(nServicesInt); nServices = static_cast<ServiceFlags>(nServicesInt); - READWRITE(*static_cast<CService*>(this)); + READWRITEAS(CService, *this); } // TODO: make private (improves encapsulation) 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/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 591777672e..59ceff247c 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -415,7 +415,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(static_cast<CScriptBase&>(*this)); + READWRITEAS(CScriptBase, *this); } CScript& operator+=(const CScript& b) @@ -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 e90b041cc2..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; @@ -155,7 +166,12 @@ enum SER_GETHASH = (1 << 2), }; -#define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) +//! Convert the reference base type to X, without changing constness or reference type. +template<typename X> X& ReadWriteAsHelper(X& x) { return x; } +template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; } + +#define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) +#define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj))) /** * Implement three methods for serializable objects. These are actually wrappers over @@ -411,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: @@ -461,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/txdb.h b/src/txdb.h index ad76b3257d..f3454e7d09 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -47,7 +47,7 @@ struct CDiskTxPos : public CDiskBlockPos template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*static_cast<CDiskBlockPos*>(this)); + READWRITEAS(CDiskBlockPos, *this); READWRITE(VARINT(nTxOffset)); } diff --git a/src/util.h b/src/util.h index 3952461e48..18d2076a05 100644 --- a/src/util.h +++ b/src/util.h @@ -145,14 +145,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/validation.cpp b/src/validation.cpp index 4a6c4066fc..cbbc857fdc 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); @@ -2064,6 +2065,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 +2205,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 +3462,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/feebumper.cpp b/src/wallet/feebumper.cpp index 82a5017de0..5c34b39ec8 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -194,7 +194,7 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin // If the output would become dust, discard it (converting the dust to fee) poutput->nValue -= nDelta; - if (poutput->nValue <= GetDustThreshold(*poutput, ::dustRelayFee)) { + if (poutput->nValue <= GetDustThreshold(*poutput, GetDiscardRate(::feeEstimator))) { LogPrint(BCLog::RPC, "Bumping fee and discarding dust output\n"); new_fee += poutput->nValue; mtx.vout.erase(mtx.vout.begin() + nOutput); 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 170e60d485..b85f374a06 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -396,7 +396,7 @@ public: mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart); } - s << *static_cast<const CMerkleTx*>(this); + s << static_cast<const CMerkleTx&>(*this); std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev s << vUnused << mapValueCopy << vOrderForm << fTimeReceivedIsTxTime << nTimeReceived << fFromMe << fSpent; } @@ -407,7 +407,7 @@ public: Init(nullptr); char fSpent; - s >> *static_cast<CMerkleTx*>(this); + s >> static_cast<CMerkleTx&>(*this); std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev s >> vUnused >> mapValue >> vOrderForm >> fTimeReceivedIsTxTime >> nTimeReceived >> fFromMe >> fSpent; @@ -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); |