diff options
Diffstat (limited to 'src')
51 files changed, 375 insertions, 281 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 019799eb0b..c4ee5f5fcc 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -8,6 +8,7 @@ TEST_SRCDIR = test TEST_BINARY=test/test_bitcoin$(EXEEXT) JSON_TEST_FILES = \ + test/data/script_tests.json \ test/data/base58_encode_decode.json \ test/data/blockfilters.json \ test/data/key_io_valid.json \ @@ -95,6 +96,15 @@ BITCOIN_TESTS =\ test/validation_block_tests.cpp \ test/versionbits_tests.cpp +if ENABLE_PROPERTY_TESTS +BITCOIN_TESTS += \ + test/key_properties.cpp + +BITCOIN_TEST_SUITE += \ + test/gen/crypto_gen.cpp \ + test/gen/crypto_gen.h +endif + if ENABLE_WALLET BITCOIN_TESTS += \ wallet/test/psbt_wallet_tests.cpp \ @@ -118,7 +128,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) +test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static if ENABLE_ZMQ diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 89149de4bb..53c3821ce5 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -46,7 +46,7 @@ static void SetupCliArgs() gArgs.AddArg("-named", strprintf("Pass named instead of positional arguments (default: %s)", DEFAULT_NAMED), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcclienttimeout=<n>", strprintf("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcconnect=<ip>", strprintf("Send commands to node running on <ip> (default: %s)", DEFAULT_RPCCONNECT), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-rpccookiefile=<loc>", _("Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)"), false, OptionsCategory::OPTIONS); + gArgs.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", false, OptionsCategory::OPTIONS); diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index b17ff3507d..4c57965bec 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -162,7 +162,7 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c break; } - LogPrint(BCLog::CMPCTBLOCK, "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), GetSerializeSize(cmpctblock, SER_NETWORK, PROTOCOL_VERSION)); + LogPrint(BCLog::CMPCTBLOCK, "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), GetSerializeSize(cmpctblock, PROTOCOL_VERSION)); return READ_STATUS_OK; } diff --git a/src/coins.cpp b/src/coins.cpp index da1036acfb..f125b483bb 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -244,7 +244,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const return true; } -static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION); +static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), PROTOCOL_VERSION); static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT; const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid) diff --git a/src/coins.h b/src/coins.h index 41a422f485..3867a37b39 100644 --- a/src/coins.h +++ b/src/coins.h @@ -285,8 +285,8 @@ public: * Note that lightweight clients may not know anything besides the hash of previous transactions, * so may not be able to calculate this. * - * @param[in] tx transaction for which we are checking input total - * @return Sum of value of all inputs (scriptSigs) + * @param[in] tx transaction for which we are checking input total + * @return Sum of value of all inputs (scriptSigs) */ CAmount GetValueIn(const CTransaction& tx) const; diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index be73d0a2f9..0628ec1d47 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -164,7 +164,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe if (tx.vout.empty()) return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) - if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) + if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values diff --git a/src/consensus/validation.h b/src/consensus/validation.h index 008eda69b2..f2e2c3585a 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -95,16 +95,16 @@ public: // weight = (stripped_size * 3) + total_size. static inline int64_t GetTransactionWeight(const CTransaction& tx) { - return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION); } static inline int64_t GetBlockWeight(const CBlock& block) { - return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION); } static inline int64_t GetTransactionInputWeight(const CTxIn& txin) { // scriptWitness size is added here because witnesses and txins are split up in segwit serialization. - return ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION); } #endif // BITCOIN_CONSENSUS_VALIDATION_H diff --git a/src/core_write.cpp b/src/core_write.cpp index 55dcb1661d..b86490716f 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -181,7 +181,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, entry.pushKV("txid", tx.GetHash().GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); entry.pushKV("version", tx.nVersion); - entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)); + entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION)); entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR); entry.pushKV("weight", GetTransactionWeight(tx)); entry.pushKV("locktime", (int64_t)tx.nLockTime); diff --git a/src/fs.cpp b/src/fs.cpp index 2dbc13643b..a34a88216a 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -11,7 +11,12 @@ namespace fsbridge { FILE *fopen(const fs::path& p, const char *mode) { +#ifndef WIN32 return ::fopen(p.string().c_str(), mode); +#else + std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> utf8_cvt; + return ::_wfopen(p.wstring().c_str(), utf8_cvt.from_bytes(mode).c_str()); +#endif } #ifndef WIN32 diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp index c85030e18e..f606c8993c 100644 --- a/src/index/txindex.cpp +++ b/src/index/txindex.cpp @@ -250,7 +250,7 @@ bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex) vPos.reserve(block.vtx.size()); for (const auto& tx : block.vtx) { vPos.emplace_back(tx->GetHash(), pos); - pos.nTxOffset += ::GetSerializeSize(*tx, SER_DISK, CLIENT_VERSION); + pos.nTxOffset += ::GetSerializeSize(*tx, CLIENT_VERSION); } return m_db->WriteTxs(vPos); } diff --git a/src/init.cpp b/src/init.cpp index 56789385d5..ff8f3cb753 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -361,7 +361,7 @@ void SetupServerArgs() "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >=%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), false, OptionsCategory::OPTIONS); gArgs.AddArg("-reindex", "Rebuild chain state and block index from the blk*.dat files on disk", false, OptionsCategory::OPTIONS); - gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks", false, OptionsCategory::OPTIONS); + gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead.", false, OptionsCategory::OPTIONS); #ifndef WIN32 gArgs.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", false, OptionsCategory::OPTIONS); #else @@ -1218,7 +1218,19 @@ bool AppInitMain() LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime())); LogPrintf("Default data directory %s\n", GetDefaultDataDir().string()); LogPrintf("Using data directory %s\n", GetDataDir().string()); - LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string()); + + // Only log conf file usage message if conf file actually exists. + fs::path config_file_path = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + if (fs::exists(config_file_path)) { + LogPrintf("Config file: %s\n", config_file_path.string()); + } else if (gArgs.IsArgSet("-conf")) { + // Warn if no conf file exists at path provided by user + InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string())); + } else { + // Not categorizing as "Warning" because it's the default behavior + LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string()); + } + LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD); // Warn about relative -datadir path. diff --git a/src/net.cpp b/src/net.cpp index c51a1b4a74..f83f39a67d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2167,7 +2167,7 @@ void Discover() } } } -#else +#elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS) // Get local host ip struct ifaddrs* myaddrs; if (getifaddrs(&myaddrs) == 0) diff --git a/src/net_processing.h b/src/net_processing.h index f16d00032e..496c3c7b0d 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -15,7 +15,7 @@ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default number of orphan+recently-replaced txn to keep around for block reconstruction */ static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100; /** Default for BIP61 (sending reject messages) */ -static constexpr bool DEFAULT_ENABLE_BIP61 = true; +static constexpr bool DEFAULT_ENABLE_BIP61{false}; class PeerLogicValidation final : public CValidationInterface, public NetEventsInterface { private: diff --git a/src/noui.cpp b/src/noui.cpp index 3a1ec2d050..df4bfabb66 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -14,7 +14,7 @@ #include <boost/signals2/connection.hpp> -static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) +bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { bool fSecure = style & CClientUIInterface::SECURE; style &= ~CClientUIInterface::SECURE; @@ -41,19 +41,18 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str return false; } -static bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) +bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) { return noui_ThreadSafeMessageBox(message, caption, style); } -static void noui_InitMessage(const std::string& message) +void noui_InitMessage(const std::string& message) { LogPrintf("init message: %s\n", message); } void noui_connect() { - // Connect bitcoind signal handlers uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox); uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion); uiInterface.InitMessage_connect(noui_InitMessage); diff --git a/src/noui.h b/src/noui.h index ff16cc9aa8..169c2bbd7f 100644 --- a/src/noui.h +++ b/src/noui.h @@ -5,6 +5,16 @@ #ifndef BITCOIN_NOUI_H #define BITCOIN_NOUI_H -extern void noui_connect(); +#include <string> + +/** Non-GUI handler, which logs and prints messages. */ +bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style); +/** Non-GUI handler, which logs and prints questions. */ +bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style); +/** Non-GUI handler, which only logs a message. */ +void noui_InitMessage(const std::string& message); + +/** Connect all bitcoind signal handlers */ +void noui_connect(); #endif // BITCOIN_NOUI_H diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 47d6644551..ac1b75edb4 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -34,7 +34,7 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn) if (txout.scriptPubKey.IsUnspendable()) return 0; - size_t nSize = GetSerializeSize(txout, SER_DISK, 0); + size_t nSize = GetSerializeSize(txout); int witnessversion = 0; std::vector<unsigned char> witnessprogram; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 59865a5eab..bdb470470e 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -93,7 +93,7 @@ CAmount CTransaction::GetValueOut() const unsigned int CTransaction::GetTotalSize() const { - return ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(*this, PROTOCOL_VERSION); } std::string CTransaction::ToString() const diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index f1d3074c2f..87282a961f 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -28,6 +28,7 @@ #include <interfaces/handler.h> #include <interfaces/node.h> +#include <noui.h> #include <rpc/server.h> #include <ui_interface.h> #include <uint256.h> @@ -71,9 +72,9 @@ Q_DECLARE_METATYPE(bool*) Q_DECLARE_METATYPE(CAmount) Q_DECLARE_METATYPE(uint256) -static void InitMessage(const std::string &message) +static void InitMessage(const std::string& message) { - LogPrintf("init message: %s\n", message); + noui_InitMessage(message); } /** Translate string to current locale using Qt. */ diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 632ce0750a..51aff08c42 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -31,6 +31,7 @@ #include <chainparams.h> #include <interfaces/handler.h> #include <interfaces/node.h> +#include <noui.h> #include <ui_interface.h> #include <util.h> @@ -1217,8 +1218,11 @@ void BitcoinGUI::showModalOverlay() modalOverlay->toggleVisibility(); } -static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style) +static bool ThreadSafeMessageBox(BitcoinGUI* gui, const std::string& message, const std::string& caption, unsigned int style) { + // Redundantly log and print message in non-gui fashion + noui_ThreadSafeMessageBox(message, caption, style); + bool modal = (style & CClientUIInterface::MODAL); // The SECURE flag has no effect in the Qt GUI. // bool secure = (style & CClientUIInterface::SECURE); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index bbf60d96fd..7afe25d25a 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -38,8 +38,6 @@ #include <shlwapi.h> #endif -#include <boost/scoped_array.hpp> - #include <QAbstractItemView> #include <QApplication> #include <QClipboard> @@ -548,40 +546,28 @@ bool SetStartOnSystemStartup(bool fAutoStart) CoInitialize(nullptr); // Get a pointer to the IShellLink interface. - IShellLink* psl = nullptr; + IShellLinkW* psl = nullptr; HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, - CLSCTX_INPROC_SERVER, IID_IShellLink, + CLSCTX_INPROC_SERVER, IID_IShellLinkW, reinterpret_cast<void**>(&psl)); if (SUCCEEDED(hres)) { // Get the current executable path - TCHAR pszExePath[MAX_PATH]; - GetModuleFileName(nullptr, pszExePath, sizeof(pszExePath)); + WCHAR pszExePath[MAX_PATH]; + GetModuleFileNameW(nullptr, pszExePath, ARRAYSIZE(pszExePath)); // Start client minimized QString strArgs = "-min"; // Set -testnet /-regtest options strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", gArgs.GetBoolArg("-testnet", false), gArgs.GetBoolArg("-regtest", false))); -#ifdef UNICODE - boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]); - // Convert the QString to TCHAR* - strArgs.toWCharArray(args.get()); - // Add missing '\0'-termination to string - args[strArgs.length()] = '\0'; -#endif - // Set the path to the shortcut target psl->SetPath(pszExePath); - PathRemoveFileSpec(pszExePath); + PathRemoveFileSpecW(pszExePath); psl->SetWorkingDirectory(pszExePath); psl->SetShowCmd(SW_SHOWMINNOACTIVE); -#ifndef UNICODE - psl->SetArguments(strArgs.toStdString().c_str()); -#else - psl->SetArguments(args.get()); -#endif + psl->SetArguments(strArgs.toStdWString().c_str()); // Query IShellLink for the IPersistFile interface for // saving the shortcut in persistent storage. @@ -589,11 +575,8 @@ bool SetStartOnSystemStartup(bool fAutoStart) hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf)); if (SUCCEEDED(hres)) { - WCHAR pwsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); // Save the link by calling IPersistFile::Save. - hres = ppf->Save(pwsz, TRUE); + hres = ppf->Save(StartupShortcutPath().wstring().c_str(), TRUE); ppf->Release(); psl->Release(); CoUninitialize(); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6fb04ab005..439427cd7e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -121,8 +121,8 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; result.pushKV("confirmations", confirmations); - result.pushKV("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)); - result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); + result.pushKV("strippedsize", (int)::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)); + result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION)); result.pushKV("weight", (int)::GetBlockWeight(block)); result.pushKV("height", blockindex->nHeight); result.pushKV("version", block.nVersion); @@ -1831,7 +1831,7 @@ static UniValue getblockstats(const JSONRPCRequest& request) if (loop_outputs) { for (const CTxOut& out : tx->vout) { tx_total_out += out.nValue; - utxo_size_inc += GetSerializeSize(out, SER_NETWORK, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + utxo_size_inc += GetSerializeSize(out, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; } } @@ -1882,7 +1882,7 @@ static UniValue getblockstats(const JSONRPCRequest& request) CTxOut prevoutput = tx_in->vout[in.prevout.n]; tx_total_in += prevoutput.nValue; - utxo_size_inc -= GetSerializeSize(prevoutput, SER_NETWORK, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + utxo_size_inc -= GetSerializeSize(prevoutput, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; } CAmount txfee = tx_total_in - tx_total_out; @@ -2192,6 +2192,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) return result; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -2227,6 +2228,7 @@ static const CRPCCommand commands[] = { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} }, { "hidden", "syncwithvalidationinterfacequeue", &syncwithvalidationinterfacequeue, {} }, }; +// clang-format on void RegisterBlockchainRPCCommands(CRPCTable &t) { diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 784d6416cf..f4d44fc809 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -18,6 +18,7 @@ public: std::string paramName; //!< parameter name }; +// clang-format off /** * Specify a (method, idx, name) here if the argument is a non-string RPC * argument and needs to be converted from JSON. @@ -163,6 +164,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "rescanblockchain", 1, "stop_height"}, { "createwallet", 1, "disable_private_keys"}, }; +// clang-format on class CRPCConvertTable { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 621b86eec8..885ad834cf 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -968,6 +968,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request) return result; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -986,6 +987,7 @@ static const CRPCCommand commands[] = { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} }, }; +// clang-format on void RegisterMiningRPCCommands(CRPCTable &t) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index b7d05cef11..0f3b601414 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -439,6 +439,7 @@ static UniValue echo(const JSONRPCRequest& request) return request.params; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -454,6 +455,7 @@ static const CRPCCommand commands[] = { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, }; +// clang-format on void RegisterMiscRPCCommands(CRPCTable &t) { diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 169a452659..099a7cf1da 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -626,6 +626,7 @@ static UniValue setnetworkactive(const JSONRPCRequest& request) return g_connman->GetNetworkActive(); } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -642,6 +643,7 @@ static const CRPCCommand commands[] = { "network", "clearbanned", &clearbanned, {} }, { "network", "setnetworkactive", &setnetworkactive, {"state"} }, }; +// clang-format on void RegisterNetRPCCommands(CRPCTable &t) { diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 6acf383646..798d54f35d 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1695,6 +1695,7 @@ UniValue converttopsbt(const JSONRPCRequest& request) return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size()); } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -1716,6 +1717,7 @@ static const CRPCCommand commands[] = { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} }, { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} }, }; +// clang-format on void RegisterRawTransactionRPCCommands(CRPCTable &t) { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 7d7e83fea8..8f3fe31ce8 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -252,6 +252,7 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest) return GetTime() - GetStartupTime(); } +// clang-format off /** * Call Table */ @@ -263,6 +264,7 @@ static const CRPCCommand vRPCCommands[] = { "control", "stop", &stop, {} }, { "control", "uptime", &uptime, {} }, }; +// clang-format on CRPCTable::CRPCTable() { diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 01cfeb23f1..15e204062f 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -88,7 +88,7 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP CTransaction tx(deserialize, stream); if (nIn >= tx.vin.size()) return set_error(err, bitcoinconsensus_ERR_TX_INDEX); - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) + if (GetSerializeSize(tx, PROTOCOL_VERSION) != txToLen) return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); // Regardless of the verification result, the tx did not error. diff --git a/src/script/sign.h b/src/script/sign.h index 18b7320998..2fc4575e59 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -147,7 +147,7 @@ static constexpr uint8_t PSBT_SEPARATOR = 0x00; template<typename Stream, typename... X> void SerializeToVector(Stream& s, const X&... args) { - WriteCompactSize(s, GetSerializeSizeMany(s, args...)); + WriteCompactSize(s, GetSerializeSizeMany(s.GetVersion(), args...)); SerializeMany(s, args...); } diff --git a/src/serialize.h b/src/serialize.h index 8bd3ef5d76..2d0cfbbbf0 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -901,10 +901,9 @@ class CSizeComputer protected: size_t nSize; - const int nType; const int nVersion; public: - CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {} + explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {} void write(const char *psz, size_t _nSize) { @@ -929,7 +928,6 @@ public: } int GetVersion() const { return nVersion; } - int GetType() const { return nType; } }; template<typename Stream> @@ -980,21 +978,15 @@ inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize) } template <typename T> -size_t GetSerializeSize(const T& t, int nType, int nVersion = 0) +size_t GetSerializeSize(const T& t, int nVersion = 0) { - return (CSizeComputer(nType, nVersion) << t).size(); + return (CSizeComputer(nVersion) << t).size(); } -template <typename S, typename T> -size_t GetSerializeSize(const S& s, const T& t) +template <typename... T> +size_t GetSerializeSizeMany(int nVersion, const T&... t) { - return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size(); -} - -template <typename S, typename... T> -size_t GetSerializeSizeMany(const S& s, const T&... t) -{ - CSizeComputer sc(s.GetType(), s.GetVersion()); + CSizeComputer sc(nVersion); SerializeMany(sc, t...); return sc.size(); } diff --git a/src/test/gen/crypto_gen.cpp b/src/test/gen/crypto_gen.cpp new file mode 100644 index 0000000000..ca8c65806f --- /dev/null +++ b/src/test/gen/crypto_gen.cpp @@ -0,0 +1,19 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <test/gen/crypto_gen.h> + +#include <key.h> + +#include <rapidcheck/gen/Arbitrary.h> +#include <rapidcheck/Gen.h> +#include <rapidcheck/gen/Predicate.h> +#include <rapidcheck/gen/Container.h> + +/** Generates 1 to 20 keys for OP_CHECKMULTISIG */ +rc::Gen<std::vector<CKey>> MultisigKeys() +{ + return rc::gen::suchThat(rc::gen::arbitrary<std::vector<CKey>>(), [](const std::vector<CKey>& keys) { + return keys.size() >= 1 && keys.size() <= 15; + }); +}; diff --git a/src/test/gen/crypto_gen.h b/src/test/gen/crypto_gen.h new file mode 100644 index 0000000000..7c2fb0350f --- /dev/null +++ b/src/test/gen/crypto_gen.h @@ -0,0 +1,63 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_TEST_GEN_CRYPTO_GEN_H +#define BITCOIN_TEST_GEN_CRYPTO_GEN_H + +#include <key.h> +#include <random.h> +#include <uint256.h> +#include <rapidcheck/gen/Arbitrary.h> +#include <rapidcheck/Gen.h> +#include <rapidcheck/gen/Create.h> +#include <rapidcheck/gen/Numeric.h> + +/** Generates 1 to 15 keys for OP_CHECKMULTISIG */ +rc::Gen<std::vector<CKey>> MultisigKeys(); + +namespace rc +{ +/** Generator for a new CKey */ +template <> +struct Arbitrary<CKey> { + static Gen<CKey> arbitrary() + { + return rc::gen::map<int>([](int x) { + CKey key; + key.MakeNewKey(true); + return key; + }); + }; +}; + +/** Generator for a CPrivKey */ +template <> +struct Arbitrary<CPrivKey> { + static Gen<CPrivKey> arbitrary() + { + return gen::map(gen::arbitrary<CKey>(), [](const CKey& key) { + return key.GetPrivKey(); + }); + }; +}; + +/** Generator for a new CPubKey */ +template <> +struct Arbitrary<CPubKey> { + static Gen<CPubKey> arbitrary() + { + return gen::map(gen::arbitrary<CKey>(), [](const CKey& key) { + return key.GetPubKey(); + }); + }; +}; +/** Generates a arbitrary uint256 */ +template <> +struct Arbitrary<uint256> { + static Gen<uint256> arbitrary() + { + return rc::gen::just(GetRandHash()); + }; +}; +} //namespace rc +#endif diff --git a/src/test/key_properties.cpp b/src/test/key_properties.cpp new file mode 100644 index 0000000000..14e3c85359 --- /dev/null +++ b/src/test/key_properties.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <key.h> + +#include <base58.h> +#include <script/script.h> +#include <uint256.h> +#include <util.h> +#include <utilstrencodings.h> +#include <test/test_bitcoin.h> +#include <string> +#include <vector> + +#include <boost/test/unit_test.hpp> +#include <rapidcheck/boost_test.h> +#include <rapidcheck/gen/Arbitrary.h> +#include <rapidcheck/Gen.h> + +#include <test/gen/crypto_gen.h> + +BOOST_FIXTURE_TEST_SUITE(key_properties, BasicTestingSetup) + +/** Check CKey uniqueness */ +RC_BOOST_PROP(key_uniqueness, (const CKey& key1, const CKey& key2)) +{ + RC_ASSERT(!(key1 == key2)); +} + +/** Verify that a private key generates the correct public key */ +RC_BOOST_PROP(key_generates_correct_pubkey, (const CKey& key)) +{ + CPubKey pubKey = key.GetPubKey(); + RC_ASSERT(key.VerifyPubKey(pubKey)); +} + +/** Create a CKey using the 'Set' function must give us the same key */ +RC_BOOST_PROP(key_set_symmetry, (const CKey& key)) +{ + CKey key1; + key1.Set(key.begin(), key.end(), key.IsCompressed()); + RC_ASSERT(key1 == key); +} + +/** Create a CKey, sign a piece of data, then verify it with the public key */ +RC_BOOST_PROP(key_sign_symmetry, (const CKey& key, const uint256& hash)) +{ + std::vector<unsigned char> vchSig; + key.Sign(hash, vchSig, 0); + const CPubKey& pubKey = key.GetPubKey(); + RC_ASSERT(pubKey.Verify(hash, vchSig)); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index eb0e4219d3..3eb8aa14fd 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -139,7 +139,7 @@ static void TestPackageSelection(const CChainParams& chainparams, const CScript& tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee uint256 hashFreeTx = tx.GetHash(); mempool.addUnchecked(entry.Fee(0).FromTx(tx)); - size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + size_t freeTxSize = ::GetSerializeSize(tx, PROTOCOL_VERSION); // Calculate a fee on child transaction that will put the package just // below the block min tx fee (assuming 1 child tx of the same size). diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 3a06145861..e754996d2f 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -182,13 +182,13 @@ BOOST_AUTO_TEST_CASE(varints) CDataStream::size_type size = 0; for (int i = 0; i < 100000; i++) { ss << VARINT(i, VarIntMode::NONNEGATIVE_SIGNED); - size += ::GetSerializeSize(VARINT(i, VarIntMode::NONNEGATIVE_SIGNED), 0, 0); + size += ::GetSerializeSize(VARINT(i, VarIntMode::NONNEGATIVE_SIGNED), 0); BOOST_CHECK(size == ss.size()); } for (uint64_t i = 0; i < 100000000000ULL; i += 999999937) { ss << VARINT(i); - size += ::GetSerializeSize(VARINT(i), 0, 0); + size += ::GetSerializeSize(VARINT(i), 0); BOOST_CHECK(size == ss.size()); } diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index f91b633b83..cca5e20296 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -184,8 +184,8 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(OneL.begin() + 32 == OneL.end()); BOOST_CHECK(MaxL.begin() + 32 == MaxL.end()); BOOST_CHECK(TmpL.begin() + 32 == TmpL.end()); - BOOST_CHECK(GetSerializeSize(R1L, 0, PROTOCOL_VERSION) == 32); - BOOST_CHECK(GetSerializeSize(ZeroL, 0, PROTOCOL_VERSION) == 32); + BOOST_CHECK(GetSerializeSize(R1L, PROTOCOL_VERSION) == 32); + BOOST_CHECK(GetSerializeSize(ZeroL, PROTOCOL_VERSION) == 32); CDataStream ss(0, PROTOCOL_VERSION); ss << R1L; @@ -230,8 +230,8 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(OneS.begin() + 20 == OneS.end()); BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); - BOOST_CHECK(GetSerializeSize(R1S, 0, PROTOCOL_VERSION) == 20); - BOOST_CHECK(GetSerializeSize(ZeroS, 0, PROTOCOL_VERSION) == 20); + BOOST_CHECK(GetSerializeSize(R1S, PROTOCOL_VERSION) == 20); + BOOST_CHECK(GetSerializeSize(ZeroS, PROTOCOL_VERSION) == 20); ss << R1S; BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20)); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 39434e4bb6..3ad93342c4 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -156,9 +156,9 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr // GetMemPoolParents() is only valid for entries in the mempool, so we // iterate mapTx to find parents. for (unsigned int i = 0; i < tx.vin.size(); i++) { - txiter piter = mapTx.find(tx.vin[i].prevout.hash); - if (piter != mapTx.end()) { - parentHashes.insert(piter); + boost::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash); + if (piter) { + parentHashes.insert(*piter); if (parentHashes.size() + 1 > limitAncestorCount) { errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount); return false; @@ -364,12 +364,10 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces // Update transaction for any feeDelta created by PrioritiseTransaction // TODO: refactor so that the fee delta is calculated before inserting // into mapTx. - std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(entry.GetTx().GetHash()); - if (pos != mapDeltas.end()) { - const CAmount &delta = pos->second; - if (delta) { + CAmount delta{0}; + ApplyDelta(entry.GetTx().GetHash(), delta); + if (delta) { mapTx.modify(newit, update_fee_delta(delta)); - } } // Update cachedInnerUsage to include contained transaction's usage. @@ -391,11 +389,8 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces // to clean up the mess we're leaving here. // Update ancestors with information about this tx - for (const uint256 &phash : setParentTransactions) { - txiter pit = mapTx.find(phash); - if (pit != mapTx.end()) { + for (const auto& pit : GetIterSet(setParentTransactions)) { UpdateParent(newit, pit, true); - } } UpdateAncestorsOf(true, newit, setAncestors); UpdateEntryForAncestors(newit, setAncestors); @@ -864,6 +859,29 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash) mapDeltas.erase(hash); } +const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const +{ + const auto it = mapNextTx.find(prevout); + return it == mapNextTx.end() ? nullptr : it->second; +} + +boost::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const uint256& txid) const +{ + auto it = mapTx.find(txid); + if (it != mapTx.end()) return it; + return boost::optional<txiter>{}; +} + +CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) const +{ + CTxMemPool::setEntries ret; + for (const auto& h : hashes) { + const auto mi = GetIter(h); + if (mi) ret.insert(*mi); + } + return ret; +} + bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const { for (unsigned int i = 0; i < tx.vin.size(); i++) diff --git a/src/txmempool.h b/src/txmempool.h index 2163b5eb21..913501fd66 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -566,7 +566,15 @@ public: void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const; void ClearPrioritisation(const uint256 hash); -public: + /** Get the transaction in the pool that spends the same prevout */ + const CTransaction* GetConflictTx(const COutPoint& prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs); + + /** Returns an iterator to the given hash, if found */ + boost::optional<txiter> GetIter(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs); + + /** Translate a set of hashes into a set of pool iterators to avoid repeated lookups */ + setEntries GetIterSet(const std::set<uint256>& hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs); + /** Remove a set of transactions from the mempool. * If a transaction is in this set, then all in-mempool descendants must * also be in the set, unless this transaction is being removed for being @@ -639,7 +647,7 @@ public: return totalTxSize; } - bool exists(uint256 hash) const + bool exists(const uint256& hash) const { LOCK(cs); return (mapTx.count(hash) != 0); diff --git a/src/undo.h b/src/undo.h index 4a78238944..4ed3dc4ca0 100644 --- a/src/undo.h +++ b/src/undo.h @@ -61,7 +61,7 @@ public: explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {} }; -static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION); +static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), PROTOCOL_VERSION); static const size_t MAX_INPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_INPUT_WEIGHT; /** Undo information for a CTransaction */ diff --git a/src/univalue/gen/gen.cpp b/src/univalue/gen/gen.cpp index 17f361941d..85fe20924a 100644 --- a/src/univalue/gen/gen.cpp +++ b/src/univalue/gen/gen.cpp @@ -12,8 +12,6 @@ #include <string.h> #include "univalue.h" -using namespace std; - static bool initEscapes; static std::string escapes[256]; diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index c15b2f051e..91b104e56e 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -15,7 +15,6 @@ #include <cassert> #include <sstream> // .get_int64() -#include <utility> // std::pair class UniValue { public: @@ -177,76 +176,9 @@ public: const UniValue& get_array() const; enum VType type() const { return getType(); } - bool push_back(std::pair<std::string,UniValue> pear) { - return pushKV(pear.first, pear.second); - } friend const UniValue& find_value( const UniValue& obj, const std::string& name); }; -// -// The following were added for compatibility with json_spirit. -// Most duplicate other methods, and should be removed. -// -static inline std::pair<std::string,UniValue> Pair(const char *cKey, const char *cVal) -{ - std::string key(cKey); - UniValue uVal(cVal); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(const char *cKey, std::string strVal) -{ - std::string key(cKey); - UniValue uVal(strVal); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(const char *cKey, uint64_t u64Val) -{ - std::string key(cKey); - UniValue uVal(u64Val); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(const char *cKey, int64_t i64Val) -{ - std::string key(cKey); - UniValue uVal(i64Val); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(const char *cKey, bool iVal) -{ - std::string key(cKey); - UniValue uVal(iVal); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(const char *cKey, int iVal) -{ - std::string key(cKey); - UniValue uVal(iVal); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(const char *cKey, double dVal) -{ - std::string key(cKey); - UniValue uVal(dVal); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(const char *cKey, const UniValue& uVal) -{ - std::string key(cKey); - return std::make_pair(key, uVal); -} - -static inline std::pair<std::string,UniValue> Pair(std::string key, const UniValue& uVal) -{ - return std::make_pair(key, uVal); -} - enum jtokentype { JTOK_ERR = -1, JTOK_NONE = 0, // eof diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index d8ad7c4b90..4c9c15d63e 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -10,8 +10,6 @@ #include "univalue.h" -using namespace std; - const UniValue NullUniValue; void UniValue::clear() @@ -37,15 +35,15 @@ bool UniValue::setBool(bool val_) return true; } -static bool validNumStr(const string& s) +static bool validNumStr(const std::string& s) { - string tokenVal; + std::string tokenVal; unsigned int consumed; enum jtokentype tt = getJsonToken(tokenVal, consumed, s.data(), s.data() + s.size()); return (tt == JTOK_NUMBER); } -bool UniValue::setNumStr(const string& val_) +bool UniValue::setNumStr(const std::string& val_) { if (!validNumStr(val_)) return false; @@ -58,7 +56,7 @@ bool UniValue::setNumStr(const string& val_) bool UniValue::setInt(uint64_t val_) { - ostringstream oss; + std::ostringstream oss; oss << val_; @@ -67,7 +65,7 @@ bool UniValue::setInt(uint64_t val_) bool UniValue::setInt(int64_t val_) { - ostringstream oss; + std::ostringstream oss; oss << val_; @@ -76,7 +74,7 @@ bool UniValue::setInt(int64_t val_) bool UniValue::setFloat(double val_) { - ostringstream oss; + std::ostringstream oss; oss << std::setprecision(16) << val_; @@ -85,7 +83,7 @@ bool UniValue::setFloat(double val_) return ret; } -bool UniValue::setStr(const string& val_) +bool UniValue::setStr(const std::string& val_) { clear(); typ = VSTR; diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp index ae75cb462a..14834db24d 100644 --- a/src/univalue/lib/univalue_read.cpp +++ b/src/univalue/lib/univalue_read.cpp @@ -8,8 +8,6 @@ #include "univalue.h" #include "univalue_utffilter.h" -using namespace std; - static bool json_isdigit(int ch) { return ((ch >= '0') && (ch <= '9')); @@ -42,7 +40,7 @@ static const char *hatoui(const char *first, const char *last, return first; } -enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, +enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, const char *raw, const char *end) { tokenVal.clear(); @@ -114,7 +112,7 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, case '8': case '9': { // part 1: int - string numStr; + std::string numStr; const char *first = raw; @@ -174,7 +172,7 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, case '"': { raw++; // skip " - string valStr; + std::string valStr; JSONUTF8StringFilter writer(valStr); while (true) { @@ -255,9 +253,9 @@ bool UniValue::read(const char *raw, size_t size) clear(); uint32_t expectMask = 0; - vector<UniValue*> stack; + std::vector<UniValue*> stack; - string tokenVal; + std::string tokenVal; unsigned int consumed; enum jtokentype tok = JTOK_NONE; enum jtokentype last_tok = JTOK_NONE; diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp index cf27835991..827eb9b271 100644 --- a/src/univalue/lib/univalue_write.cpp +++ b/src/univalue/lib/univalue_write.cpp @@ -8,11 +8,9 @@ #include "univalue.h" #include "univalue_escapes.h" -using namespace std; - -static string json_escape(const string& inS) +static std::string json_escape(const std::string& inS) { - string outS; + std::string outS; outS.reserve(inS.size() * 2); for (unsigned int i = 0; i < inS.size(); i++) { @@ -28,10 +26,10 @@ static string json_escape(const string& inS) return outS; } -string UniValue::write(unsigned int prettyIndent, - unsigned int indentLevel) const +std::string UniValue::write(unsigned int prettyIndent, + unsigned int indentLevel) const { - string s; + std::string s; s.reserve(1024); unsigned int modIndent = indentLevel; @@ -62,12 +60,12 @@ string UniValue::write(unsigned int prettyIndent, return s; } -static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, string& s) +static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) { s.append(prettyIndent * indentLevel, ' '); } -void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, string& s) const +void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const { s += "["; if (prettyIndent) @@ -89,7 +87,7 @@ void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, s s += "]"; } -void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, string& s) const +void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const { s += "{"; if (prettyIndent) diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp index 2c37794a4b..75c0dc225a 100644 --- a/src/univalue/test/unitester.cpp +++ b/src/univalue/test/unitester.cpp @@ -17,8 +17,7 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #endif -using namespace std; -string srcdir(JSON_TEST_SRC); +std::string srcdir(JSON_TEST_SRC); static bool test_failed = false; #define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } } @@ -30,9 +29,9 @@ static std::string rtrim(std::string s) return s; } -static void runtest(string filename, const string& jdata) +static void runtest(std::string filename, const std::string& jdata) { - string prefix = filename.substr(0, 4); + std::string prefix = filename.substr(0, 4); bool wantPass = (prefix == "pass") || (prefix == "roun"); bool wantFail = (prefix == "fail"); @@ -56,19 +55,19 @@ static void runtest(string filename, const string& jdata) static void runtest_file(const char *filename_) { - string basename(filename_); - string filename = srcdir + "/" + basename; + std::string basename(filename_); + std::string filename = srcdir + "/" + basename; FILE *f = fopen(filename.c_str(), "r"); assert(f != NULL); - string jdata; + std::string jdata; char buf[4096]; while (!feof(f)) { int bread = fread(buf, 1, sizeof(buf), f); assert(!ferror(f)); - string s(buf, bread); + std::string s(buf, bread); jdata += s; } diff --git a/src/util.cpp b/src/util.cpp index 84d8175389..84a4adcfd4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1139,14 +1139,14 @@ void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) { #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate) { - char pszPath[MAX_PATH] = ""; + WCHAR pszPath[MAX_PATH] = L""; - if(SHGetSpecialFolderPathA(nullptr, pszPath, nFolder, fCreate)) + if(SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate)) { return fs::path(pszPath); } - LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n"); + LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n"); return fs::path(""); } #endif diff --git a/src/validation.cpp b/src/validation.cpp index 7ec0c6a961..d4a84c53b5 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -584,7 +584,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // Do not work on transactions that are too small. // A transaction with 1 segwit input and 1 P2WPHK output has non-witness size of 82 bytes. // Transactions smaller than this are not relayed to reduce unnecessary malloc overhead. - if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) < MIN_STANDARD_TX_NONWITNESS_SIZE) + if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) < MIN_STANDARD_TX_NONWITNESS_SIZE) return state.DoS(0, false, REJECT_NONSTANDARD, "tx-size-small"); // Only accept nLockTime-using transactions that can be mined in the next @@ -602,10 +602,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool std::set<uint256> setConflicts; for (const CTxIn &txin : tx.vin) { - auto itConflicting = pool.mapNextTx.find(txin.prevout); - if (itConflicting != pool.mapNextTx.end()) - { - const CTransaction *ptxConflicting = itConflicting->second; + const CTransaction* ptxConflicting = pool.GetConflictTx(txin.prevout); + if (ptxConflicting) { if (!setConflicts.count(ptxConflicting->GetHash())) { // Allow opt-out of transaction replacement by setting @@ -786,16 +784,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool CFeeRate newFeeRate(nModifiedFees, nSize); std::set<uint256> setConflictsParents; const int maxDescendantsToVisit = 100; - CTxMemPool::setEntries setIterConflicting; - for (const uint256 &hashConflicting : setConflicts) - { - CTxMemPool::txiter mi = pool.mapTx.find(hashConflicting); - if (mi == pool.mapTx.end()) - continue; - - // Save these to avoid repeated lookups - setIterConflicting.insert(mi); - + const CTxMemPool::setEntries setIterConflicting = pool.GetIterSet(setConflicts); + for (const auto& mi : setIterConflicting) { // Don't allow the replacement to reduce the feerate of the // mempool. // @@ -861,11 +851,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // Rather than check the UTXO set - potentially expensive - // it's cheaper to just check if the new input refers to a // tx that's in the mempool. - if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end()) + if (pool.exists(tx.vin[j].prevout.hash)) { return state.DoS(0, false, REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false, strprintf("replacement %s adds unconfirmed input, idx %d", hash.ToString(), j)); + } } } @@ -1060,7 +1051,7 @@ static bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMes return error("WriteBlockToDisk: OpenBlockFile failed"); // Write index header - unsigned int nSize = GetSerializeSize(fileout, block); + unsigned int nSize = GetSerializeSize(block, fileout.GetVersion()); fileout << messageStart << nSize; // Write block @@ -1470,7 +1461,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint return error("%s: OpenUndoFile failed", __func__); // Write index header - unsigned int nSize = GetSerializeSize(fileout, blockundo); + unsigned int nSize = GetSerializeSize(blockundo, fileout.GetVersion()); fileout << messageStart << nSize; // Write undo data @@ -1668,7 +1659,7 @@ static bool WriteUndoDataForBlock(const CBlockUndo& blockundo, CValidationState& // Write undo information to disk if (pindex->GetUndoPos().IsNull()) { CDiskBlockPos _pos; - if (!FindUndoPos(state, pindex->nFile, _pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) + if (!FindUndoPos(state, pindex->nFile, _pos, ::GetSerializeSize(blockundo, CLIENT_VERSION) + 40)) return error("ConnectBlock(): FindUndoPos failed"); if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart())) return AbortNode(state, "Failed to write undo data"); @@ -3119,7 +3110,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P // checks that use witness data may be performed here. // Size limits - if (block.vtx.empty() || block.vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) + if (block.vtx.empty() || block.vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT || ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed"); // First transaction must be coinbase, the rest must not be @@ -3436,7 +3427,7 @@ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, CValidatio /** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */ static CDiskBlockPos SaveBlockToDisk(const CBlock& block, int nHeight, const CChainParams& chainparams, const CDiskBlockPos* dbp) { - unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); + unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION); CDiskBlockPos blockPos; if (dbp != nullptr) blockPos = *dbp; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index af36d321d5..c82d0e97d4 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -849,6 +849,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con std::vector<unsigned char> vData(ParseHex(output)); script = CScript(vData.begin(), vData.end()); + if (!ExtractDestination(script, dest) && !internal) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set to true for nonstandard scriptPubKey imports."); + } } // Watchonly and private keys @@ -861,11 +864,6 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con throw JSONRPCError(RPC_INVALID_PARAMETER, "Incompatibility found between internal and label"); } - // Not having Internal + Script - if (!internal && isScript) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set for hex scriptPubKey"); - } - // Keys / PubKeys size check. if (!isP2SH && (keys.size() > 1 || pubKeys.size() > 1)) { // Address / scriptPubKey throw JSONRPCError(RPC_INVALID_PARAMETER, "More than private key given for one address"); @@ -969,21 +967,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con CTxDestination pubkey_dest = pubKey.GetID(); // Consistency check. - if (!isScript && !(pubkey_dest == dest)) { + if (!(pubkey_dest == dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); } - // Consistency check. - if (isScript) { - CTxDestination destination; - - if (ExtractDestination(script, destination)) { - if (!(destination == pubkey_dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); - } - } - } - CScript pubKeyScript = GetScriptForDestination(pubkey_dest); if (::IsMine(*pwallet, pubKeyScript) == ISMINE_SPENDABLE) { @@ -1034,21 +1021,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con CTxDestination pubkey_dest = pubKey.GetID(); // Consistency check. - if (!isScript && !(pubkey_dest == dest)) { + if (!(pubkey_dest == dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); } - // Consistency check. - if (isScript) { - CTxDestination destination; - - if (ExtractDestination(script, destination)) { - if (!(destination == pubkey_dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); - } - } - } - CKeyID vchAddress = pubKey.GetID(); pwallet->MarkDirty(); pwallet->SetAddressBook(vchAddress, label, "receive"); @@ -1080,11 +1056,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } - if (scriptPubKey.getType() == UniValue::VOBJ) { - // add to address book or update label - if (IsValidDestination(dest)) { - pwallet->SetAddressBook(dest, label, "receive"); - } + // add to address book or update label + if (IsValidDestination(dest)) { + pwallet->SetAddressBook(dest, label, "receive"); } success = true; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e419f8d164..15f3e5947e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4065,6 +4065,7 @@ UniValue importprunedfunds(const JSONRPCRequest& request); UniValue removeprunedfunds(const JSONRPCRequest& request); UniValue importmulti(const JSONRPCRequest& request); +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -4125,6 +4126,7 @@ static const CRPCCommand commands[] = { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} }, { "wallet", "walletprocesspsbt", &walletprocesspsbt, {"psbt","sign","sighashtype","bip32derivs"} }, }; +// clang-format on void RegisterWalletRPCCommands(CRPCTable &t) { diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index a24dc1b5f9..6d1d09d5a5 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -462,14 +462,19 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) BOOST_CHECK(testWallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, filter_confirmed, GroupCoins(vCoins), setCoinsRet, nValueRet, coin_selection_params, bnb_used)); BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); + } - // test with many inputs - for (CAmount amt=1500; amt < COIN; amt*=10) { - empty_wallet(); - // Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 bytes per input) - for (uint16_t j = 0; j < 676; j++) - add_coin(amt); + // test with many inputs + for (CAmount amt=1500; amt < COIN; amt*=10) { + empty_wallet(); + // Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 bytes per input) + for (uint16_t j = 0; j < 676; j++) + add_coin(amt); + + // We only create the wallet once to save time, but we still run the coin selection RUN_TESTS times. + for (int i = 0; i < RUN_TESTS; i++) { BOOST_CHECK(testWallet.SelectCoinsMinConf(2000, filter_confirmed, GroupCoins(vCoins), setCoinsRet, nValueRet, coin_selection_params, bnb_used)); + if (amt - 2000 < MIN_CHANGE) { // needs more than one input: uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt); @@ -481,14 +486,17 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) BOOST_CHECK_EQUAL(nValueRet, amt); BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); } - } + } + } - // test randomness - { - empty_wallet(); - for (int i2 = 0; i2 < 100; i2++) - add_coin(COIN); + // test randomness + { + empty_wallet(); + for (int i2 = 0; i2 < 100; i2++) + add_coin(COIN); + // Again, we only create the wallet once to save time, but we still run the coin selection RUN_TESTS times. + for (int i = 0; i < RUN_TESTS; i++) { // picking 50 from 100 coins doesn't depend on the shuffle, // but does depend on randomness in the stochastic approximation code BOOST_CHECK(testWallet.SelectCoinsMinConf(50 * COIN, filter_standard, GroupCoins(vCoins), setCoinsRet , nValueRet, coin_selection_params, bnb_used)); @@ -506,17 +514,19 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) fails++; } BOOST_CHECK_NE(fails, RANDOM_REPEATS); - - // add 75 cents in small change. not enough to make 90 cents, - // then try making 90 cents. there are multiple competing "smallest bigger" coins, - // one of which should be picked at random - add_coin(5 * CENT); - add_coin(10 * CENT); - add_coin(15 * CENT); - add_coin(20 * CENT); - add_coin(25 * CENT); - - fails = 0; + } + + // add 75 cents in small change. not enough to make 90 cents, + // then try making 90 cents. there are multiple competing "smallest bigger" coins, + // one of which should be picked at random + add_coin(5 * CENT); + add_coin(10 * CENT); + add_coin(15 * CENT); + add_coin(20 * CENT); + add_coin(25 * CENT); + + for (int i = 0; i < RUN_TESTS; i++) { + int fails = 0; for (int j = 0; j < RANDOM_REPEATS; j++) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time @@ -527,8 +537,9 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test) fails++; } BOOST_CHECK_NE(fails, RANDOM_REPEATS); - } - } + } + } + empty_wallet(); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e41f829f02..593035eb78 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -687,6 +687,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) { encrypted_batch->TxnAbort(); delete encrypted_batch; + encrypted_batch = nullptr; // We now probably have half of our keys encrypted in memory, and half not... // die and let the user reload the unencrypted wallet. assert(false); @@ -697,6 +698,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) if (!encrypted_batch->TxnCommit()) { delete encrypted_batch; + encrypted_batch = nullptr; // We now have keys encrypted in memory, but not on disk... // die to avoid confusion and let the user reload the unencrypted wallet. assert(false); @@ -2655,7 +2657,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, change_type)); } CTxOut change_prototype_txout(0, scriptChange); - coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0); + coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout); CFeeRate discard_rate = GetDiscardRate(*this, ::feeEstimator); @@ -2699,7 +2701,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac } } // Include the fee cost for outputs. Note this is only used for BnB right now - coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout, SER_NETWORK, PROTOCOL_VERSION); + coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout, PROTOCOL_VERSION); if (IsDust(txout, ::dustRelayFee)) { |