aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build_msvc/common.init.vcxproj.in2
-rw-r--r--configure.ac12
-rw-r--r--src/.clang-tidy4
-rw-r--r--src/bitcoin-cli.cpp2
-rw-r--r--src/bitcoin-tx.cpp2
-rw-r--r--src/blockfilter.cpp4
-rw-r--r--src/coins.cpp2
-rw-r--r--src/core_read.cpp2
-rw-r--r--src/external_signer.cpp2
-rw-r--r--src/fs.h4
-rw-r--r--src/init.cpp2
-rw-r--r--src/logging.cpp2
-rw-r--r--src/netbase.cpp6
-rw-r--r--src/node/blockstorage.cpp2
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/rpc/mining.cpp2
-rw-r--r--src/rpc/rawtransaction_util.cpp4
-rw-r--r--src/rpc/util.cpp2
-rw-r--r--src/script/descriptor.cpp4
-rw-r--r--src/test/base58_tests.cpp4
-rw-r--r--src/test/blockfilter_tests.cpp2
-rw-r--r--src/test/descriptor_tests.cpp25
-rw-r--r--src/test/key_io_tests.cpp6
-rw-r--r--src/test/script_tests.cpp2
-rw-r--r--src/test/sighash_tests.cpp2
-rw-r--r--src/test/transaction_tests.cpp8
-rw-r--r--src/test/validation_block_tests.cpp2
-rw-r--r--src/wallet/bdb.cpp2
-rw-r--r--src/wallet/receive.cpp2
-rw-r--r--src/wallet/rpc/spend.cpp2
-rw-r--r--src/wallet/scriptpubkeyman.cpp2
-rw-r--r--src/wallet/spend.cpp16
-rw-r--r--src/wallet/wallet.cpp15
-rw-r--r--src/wallet/wallet.h1
-rw-r--r--src/wallet/walletdb.cpp6
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py25
36 files changed, 127 insertions, 57 deletions
diff --git a/build_msvc/common.init.vcxproj.in b/build_msvc/common.init.vcxproj.in
index ff3b390d0e..7f623c6296 100644
--- a/build_msvc/common.init.vcxproj.in
+++ b/build_msvc/common.init.vcxproj.in
@@ -90,7 +90,7 @@
<AdditionalOptions>/utf-8 /Zc:__cplusplus /std:c++20 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4018;4244;4267;4334;4715;4805;4834</DisableSpecificWarnings>
<TreatWarningAsError>true</TreatWarningAsError>
- <PreprocessorDefinitions>_SILENCE_CXX20_U8PATH_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;ZMQ_STATIC;NOMINMAX;WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;_WIN32_WINNT=0x0601;_WIN32_IE=0x0501;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;ZMQ_STATIC;NOMINMAX;WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;_WIN32_WINNT=0x0601;_WIN32_IE=0x0501;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src;..\..\src\minisketch\include;..\..\src\univalue\include;..\..\src\secp256k1\include;..\..\src\leveldb\include;..\..\src\leveldb\helpers\memenv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
diff --git a/configure.ac b/configure.ac
index 713b8a1ab9..1752fda344 100644
--- a/configure.ac
+++ b/configure.ac
@@ -519,7 +519,7 @@ if test "$enable_clmul" = "yes"; then
fi
TEMP_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS"
+CXXFLAGS="$SSE42_CXXFLAGS $CXXFLAGS"
AC_MSG_CHECKING([for SSE4.2 intrinsics])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdint.h>
@@ -541,7 +541,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
CXXFLAGS="$TEMP_CXXFLAGS"
TEMP_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $SSE41_CXXFLAGS"
+CXXFLAGS="$SSE41_CXXFLAGS $CXXFLAGS"
AC_MSG_CHECKING([for SSE4.1 intrinsics])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdint.h>
@@ -556,7 +556,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
CXXFLAGS="$TEMP_CXXFLAGS"
TEMP_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $AVX2_CXXFLAGS"
+CXXFLAGS="$AVX2_CXXFLAGS $CXXFLAGS"
AC_MSG_CHECKING([for AVX2 intrinsics])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdint.h>
@@ -571,7 +571,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
CXXFLAGS="$TEMP_CXXFLAGS"
TEMP_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $X86_SHANI_CXXFLAGS"
+CXXFLAGS="$X86_SHANI_CXXFLAGS $CXXFLAGS"
AC_MSG_CHECKING([for x86 SHA-NI intrinsics])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdint.h>
@@ -592,7 +592,7 @@ AX_CHECK_COMPILE_FLAG([-march=armv8-a+crc+crypto], [ARM_CRC_CXXFLAGS="-march=arm
AX_CHECK_COMPILE_FLAG([-march=armv8-a+crc+crypto], [ARM_SHANI_CXXFLAGS="-march=armv8-a+crc+crypto"], [], [$CXXFLAG_WERROR])
TEMP_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $ARM_CRC_CXXFLAGS"
+CXXFLAGS="$ARM_CRC_CXXFLAGS $CXXFLAGS"
AC_MSG_CHECKING([for ARMv8 CRC32 intrinsics])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <arm_acle.h>
@@ -611,7 +611,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
CXXFLAGS="$TEMP_CXXFLAGS"
TEMP_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS $ARM_SHANI_CXXFLAGS"
+CXXFLAGS="$ARM_SHANI_CXXFLAGS $CXXFLAGS"
AC_MSG_CHECKING([for ARMv8 SHA-NI intrinsics])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <arm_acle.h>
diff --git a/src/.clang-tidy b/src/.clang-tidy
index b9371b147b..f59f80f8ce 100644
--- a/src/.clang-tidy
+++ b/src/.clang-tidy
@@ -4,6 +4,8 @@ bugprone-argument-comment,
misc-unused-using-decls,
modernize-use-default-member-init,
modernize-use-nullptr,
+performance-for-range-copy,
+performance-unnecessary-copy-initialization,
readability-redundant-declaration,
readability-redundant-string-init,
'
@@ -12,6 +14,8 @@ bugprone-argument-comment,
misc-unused-using-decls,
modernize-use-default-member-init,
modernize-use-nullptr,
+performance-for-range-copy,
+performance-unnecessary-copy-initialization,
readability-redundant-declaration,
readability-redundant-string-init,
'
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 6ce4e05e4d..e64e2202ba 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -911,7 +911,7 @@ static void GetWalletBalances(UniValue& result)
UniValue balances(UniValue::VOBJ);
for (const UniValue& wallet : wallets.getValues()) {
- const std::string wallet_name = wallet.get_str();
+ const std::string& wallet_name = wallet.get_str();
const UniValue getbalances = ConnectAndCallRPC(&rh, "getbalances", /* args=*/{}, wallet_name);
const UniValue& balance = find_value(getbalances, "result")["mine"]["trusted"];
balances.pushKV(wallet_name, balance);
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index b006353cb0..c2bb89b8cf 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -596,7 +596,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
UniValue prevtxsObj = registers["prevtxs"];
{
for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) {
- UniValue prevOut = prevtxsObj[previdx];
+ const UniValue& prevOut = prevtxsObj[previdx];
if (!prevOut.isObject())
throw std::runtime_error("expected prevtxs internal object");
diff --git a/src/blockfilter.cpp b/src/blockfilter.cpp
index 0ff79bb3ca..43d88df720 100644
--- a/src/blockfilter.cpp
+++ b/src/blockfilter.cpp
@@ -169,7 +169,7 @@ const std::set<BlockFilterType>& AllBlockFilterTypes()
static std::once_flag flag;
std::call_once(flag, []() {
- for (auto entry : g_filter_types) {
+ for (const auto& entry : g_filter_types) {
types.insert(entry.first);
}
});
@@ -185,7 +185,7 @@ const std::string& ListBlockFilterTypes()
std::call_once(flag, []() {
std::stringstream ret;
bool first = true;
- for (auto entry : g_filter_types) {
+ for (const auto& entry : g_filter_types) {
if (!first) ret << ", ";
ret << entry.second;
first = false;
diff --git a/src/coins.cpp b/src/coins.cpp
index 1753d33b71..5983a8a39f 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -296,7 +296,7 @@ bool CCoinsViewErrorCatcher::GetCoin(const COutPoint &outpoint, Coin &coin) cons
try {
return CCoinsViewBacked::GetCoin(outpoint, coin);
} catch(const std::runtime_error& e) {
- for (auto f : m_err_callbacks) {
+ for (const auto& f : m_err_callbacks) {
f();
}
LogPrintf("Error reading from database: %s\n", e.what());
diff --git a/src/core_read.cpp b/src/core_read.cpp
index 77c516427a..ec21a2f7f4 100644
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -265,7 +265,7 @@ int ParseSighashString(const UniValue& sighash)
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
};
- std::string strHashType = sighash.get_str();
+ const std::string& strHashType = sighash.get_str();
const auto& it = map_sighash_values.find(strHashType);
if (it != map_sighash_values.end()) {
hash_type = it->second;
diff --git a/src/external_signer.cpp b/src/external_signer.cpp
index 6bab0a856c..094314e878 100644
--- a/src/external_signer.cpp
+++ b/src/external_signer.cpp
@@ -28,7 +28,7 @@ bool ExternalSigner::Enumerate(const std::string& command, std::vector<ExternalS
if (!result.isArray()) {
throw std::runtime_error(strprintf("'%s' received invalid response, expected array of signers", command));
}
- for (UniValue signer : result.getValues()) {
+ for (const UniValue& signer : result.getValues()) {
// Check for error
const UniValue& error = find_value(signer, "error");
if (!error.isNull()) {
diff --git a/src/fs.h b/src/fs.h
index e8b34319bb..ac58c4a2ba 100644
--- a/src/fs.h
+++ b/src/fs.h
@@ -69,7 +69,11 @@ public:
static inline path u8path(const std::string& utf8_str)
{
+#if __cplusplus < 202002L
return std::filesystem::u8path(utf8_str);
+#else
+ return std::filesystem::path(std::u8string{utf8_str.begin(), utf8_str.end()});
+#endif
}
// Disallow implicit std::string conversion for absolute to avoid
diff --git a/src/init.cpp b/src/init.cpp
index 488c754e95..480b8c7705 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1046,7 +1046,7 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
static bool LockDataDirectory(bool probeOnly)
{
// Make sure only a single Bitcoin process is using the data directory.
- fs::path datadir = gArgs.GetDataDirNet();
+ const fs::path& datadir = gArgs.GetDataDirNet();
if (!DirIsWritable(datadir)) {
return InitError(strprintf(_("Cannot write to data directory '%s'; check permissions."), fs::PathToString(datadir)));
}
diff --git a/src/logging.cpp b/src/logging.cpp
index 1e2c1d5a77..73c4e458bd 100644
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -364,7 +364,7 @@ void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& loggi
}
if (m_log_threadnames && m_started_new_line) {
- const auto threadname = util::ThreadGetInternalName();
+ const auto& threadname = util::ThreadGetInternalName();
str_prefixed.insert(0, "[" + (threadname.empty() ? "unknown" : threadname) + "] ");
}
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 4b8d2f8d0c..a5f7bda875 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -387,7 +387,7 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
return error("Error sending to proxy");
}
uint8_t pchRet1[2];
- if ((recvr = InterruptibleRecv(pchRet1, 2, g_socks5_recv_timeout, sock)) != IntrRecvError::OK) {
+ if (InterruptibleRecv(pchRet1, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
return false;
}
@@ -410,7 +410,7 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
}
LogPrint(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
uint8_t pchRetA[2];
- if ((recvr = InterruptibleRecv(pchRetA, 2, g_socks5_recv_timeout, sock)) != IntrRecvError::OK) {
+ if (InterruptibleRecv(pchRetA, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
return error("Error reading proxy authentication response");
}
if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
@@ -476,7 +476,7 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
if (recvr != IntrRecvError::OK) {
return error("Error reading from proxy");
}
- if ((recvr = InterruptibleRecv(pchRet3, 2, g_socks5_recv_timeout, sock)) != IntrRecvError::OK) {
+ if (InterruptibleRecv(pchRet3, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
return error("Error reading from proxy");
}
LogPrint(BCLog::NET, "SOCKS5 connected %s\n", strDest);
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index 601d0bdf58..42b6b017fe 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -415,7 +415,7 @@ void CleanupBlockRevFiles()
// Remove the rev files immediately and insert the blk file paths into an
// ordered map keyed by block file index.
LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
- fs::path blocksdir = gArgs.GetBlocksDirPath();
+ const fs::path& blocksdir = gArgs.GetBlocksDirPath();
for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
const std::string path = fs::PathToString(it->path().filename());
if (fs::is_regular_file(*it) &&
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index a4dfffa387..bf04a6dd5f 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -44,7 +44,7 @@ SplashScreen::SplashScreen(const NetworkStyle* networkStyle)
QString titleText = PACKAGE_NAME;
QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion()));
QString copyrightText = QString::fromUtf8(CopyrightHolders(strprintf("\xc2\xA9 %u-%u ", 2009, COPYRIGHT_YEAR)).c_str());
- QString titleAddText = networkStyle->getTitleAddText();
+ const QString& titleAddText = networkStyle->getTitleAddText();
QString font = QApplication::font().toString();
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index e9663d38b4..91feb2c24b 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -679,7 +679,7 @@ static RPCHelpMan getblocktemplate()
if (lpval.isStr())
{
// Format: <hashBestChain><nTransactionsUpdatedLast>
- std::string lpstr = lpval.get_str();
+ const std::string& lpstr = lpval.get_str();
hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid");
nTransactionsUpdatedLastLP = LocaleIndependentAtoi<int64_t>(lpstr.substr(64));
diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp
index b06e9f6e4b..b078ee8b29 100644
--- a/src/rpc/rawtransaction_util.cpp
+++ b/src/rpc/rawtransaction_util.cpp
@@ -160,14 +160,14 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::
void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins)
{
if (!prevTxsUnival.isNull()) {
- UniValue prevTxs = prevTxsUnival.get_array();
+ const UniValue& prevTxs = prevTxsUnival.get_array();
for (unsigned int idx = 0; idx < prevTxs.size(); ++idx) {
const UniValue& p = prevTxs[idx];
if (!p.isObject()) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
}
- UniValue prevOut = p.get_obj();
+ const UniValue& prevOut = p.get_obj();
RPCTypeCheckObj(prevOut,
{
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 7517f64ea1..24ab21a947 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -98,7 +98,7 @@ CAmount AmountFromValue(const UniValue& value, int decimals)
uint256 ParseHashV(const UniValue& v, std::string strName)
{
- std::string strHex(v.get_str());
+ const std::string& strHex(v.get_str());
if (64 != strHex.length())
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", strName, 64, strHex.length(), strHex));
if (!IsHex(strHex)) // Note: IsHex("") is false
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 8ace9c3136..434e106dad 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -1472,6 +1472,10 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
}
if (ctx == ParseScriptContext::TOP && Func("rawtr", expr)) {
auto arg = Expr(expr);
+ if (expr.size()) {
+ error = strprintf("rawtr(): only one key expected.");
+ return nullptr;
+ }
auto output_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
if (!output_key) return nullptr;
++key_exp_index;
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index 00f32ddcee..249f89ae2f 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -25,7 +25,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
{
UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test.size() < 2) // Allow for extra stuff (useful for comments)
{
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
std::vector<unsigned char> result;
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test.size() < 2) // Allow for extra stuff (useful for comments)
{
diff --git a/src/test/blockfilter_tests.cpp b/src/test/blockfilter_tests.cpp
index 178757e7b4..0831188327 100644
--- a/src/test/blockfilter_tests.cpp
+++ b/src/test/blockfilter_tests.cpp
@@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test)
const UniValue& tests = json.get_array();
for (unsigned int i = 0; i < tests.size(); i++) {
- UniValue test = tests[i];
+ const UniValue& test = tests[i];
std::string strTest = test.write();
if (test.size() == 1) {
diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp
index d9503d7624..d0ad037228 100644
--- a/src/test/descriptor_tests.cpp
+++ b/src/test/descriptor_tests.cpp
@@ -464,6 +464,31 @@ Check("sh(wsh(multi(20,KzoAz5CanayRKex3fSLQ2BwJpN7U52gZvxMyk78nDMHuqrUxuSJy,KwGN
CheckUnparsable("", "raw(asdf)", "Raw script is not hex"); // Invalid script
CheckUnparsable("", "raw(Ü)#00000000", "Invalid characters in payload"); // Invalid chars
+ Check(
+ "rawtr(xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt/86'/1'/0'/1/*)#a5gn3t7k",
+ "rawtr(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/86'/1'/0'/1/*)#4ur3xhft",
+ "",
+ "rawtr([5a61ff8e/86'/1'/0']xpub6DtZpc9PRL2B6pwoNGysmHAaBofDmWv5S6KQEKKGPKhf5fV62ywDtSziSApYVK3JnYY5KUSgiCwiXW5wtd8z7LNBxT9Mu5sEro8itdGfTeA/1/*)#llheyd9x",
+ RANGE | HARDENED | XONLY_KEYS,
+ {{"51205172af752f057d543ce8e4a6f8dcf15548ec6be44041bfa93b72e191cfc8c1ee"}, {"51201b66f20b86f700c945ecb9ad9b0ad1662b73084e2bfea48bee02126350b8a5b1"}, {"512063e70f66d815218abcc2306aa930aaca07c5cde73b75127eb27b5e8c16b58a25"}},
+ OutputType::BECH32M,
+ {{0x80000056, 0x80000001, 0x80000000, 1, 0}, {0x80000056, 0x80000001, 0x80000000, 1, 1}, {0x80000056, 0x80000001, 0x80000000, 1, 2}});
+
+
+ Check(
+ "rawtr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)",
+ "rawtr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)",
+ "rawtr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)",
+ "rawtr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)",
+ SIGNABLE | XONLY_KEYS,
+ {{"5120a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd"}},
+ OutputType::BECH32M);
+
+ CheckUnparsable(
+ "",
+ "rawtr(xpub68FQ9imX6mCWacw6eNRjaa8q8ynnHmUd5i7MVR51ZMPP5JycyfVHSLQVFPHMYiTybWJnSBL2tCBpy6aJTR2DYrshWYfwAxs8SosGXd66d8/*, xpub69Mvq3QMipdvnd9hAyeTnT5jrkcBuLErV212nsGf3qr7JPWysc9HnNhCsazdzj1etSx28hPSE8D7DnceFbNdw4Kg8SyRfjE2HFLv1P8TSGc/*)",
+ "rawtr(): only one key expected.");
+
// A 2of4 but using a direct push rather than OP_2
CScript nonminimalmultisig;
CKey keys[4];
diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp
index e70b8b3dfd..1eac68de14 100644
--- a/src/test/key_io_tests.cpp
+++ b/src/test/key_io_tests.cpp
@@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(key_io_valid_parse)
SelectParams(CBaseChainParams::MAIN);
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test.size() < 3) { // Allow for extra stuff (useful for comments)
BOOST_ERROR("Bad test: " << strTest);
@@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(key_io_valid_gen)
UniValue tests = read_json(std::string(json_tests::key_io_valid, json_tests::key_io_valid + sizeof(json_tests::key_io_valid)));
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test.size() < 3) // Allow for extra stuff (useful for comments)
{
@@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(key_io_invalid)
CTxDestination destination;
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test.size() < 1) // Allow for extra stuff (useful for comments)
{
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 9e7a376d6b..935194057c 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -942,7 +942,7 @@ BOOST_AUTO_TEST_CASE(script_json_test)
UniValue tests = read_json(std::string(json_tests::script_tests, json_tests::script_tests + sizeof(json_tests::script_tests)));
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
CScriptWitness witness;
CAmount nValue = 0;
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index 7376f2ff5c..514798d8fa 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data)
UniValue tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash)));
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test.size() < 1) // Allow for extra stuff (useful for comments)
{
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index cd6bf11327..952598f745 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test[0].isArray())
{
@@ -214,7 +214,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
fValid = false;
break;
}
- UniValue vinput = input.get_array();
+ const UniValue& vinput = input.get_array();
if (vinput.size() < 3 || vinput.size() > 4)
{
fValid = false;
@@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
for (unsigned int idx = 0; idx < tests.size(); idx++) {
- UniValue test = tests[idx];
+ const UniValue& test = tests[idx];
std::string strTest = test.write();
if (test[0].isArray())
{
@@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
fValid = false;
break;
}
- UniValue vinput = input.get_array();
+ const UniValue& vinput = input.get_array();
if (vinput.size() < 3 || vinput.size() > 4)
{
fValid = false;
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index 7a82e1a736..1c5ca18759 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -183,7 +183,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
}
// to make sure that eventually we process the full chain - do it here
- for (auto block : blocks) {
+ for (const auto& block : blocks) {
if (block->vtx.size() == 1) {
bool processed = Assert(m_node.chainman)->ProcessNewBlock(block, true, &ignored);
assert(processed);
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 60715ff3c8..deb1293cd4 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -432,7 +432,7 @@ void BerkeleyEnvironment::ReloadDbEnv()
});
std::vector<fs::path> filenames;
- for (auto it : m_databases) {
+ for (const auto& it : m_databases) {
filenames.push_back(it.first);
}
// Close the individual Db's
diff --git a/src/wallet/receive.cpp b/src/wallet/receive.cpp
index db169aad12..7fbf2ff8cf 100644
--- a/src/wallet/receive.cpp
+++ b/src/wallet/receive.cpp
@@ -416,7 +416,7 @@ std::set< std::set<CTxDestination> > GetAddressGroupings(const CWallet& wallet)
std::set< std::set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
std::map< CTxDestination, std::set<CTxDestination>* > setmap; // map addresses to the unique group containing it
- for (std::set<CTxDestination> _grouping : groupings)
+ for (const std::set<CTxDestination>& _grouping : groupings)
{
// make a set of all the groups hit by this new group
std::set< std::set<CTxDestination>* > hits;
diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp
index 8bbb862a7b..c6e7588fb4 100644
--- a/src/wallet/rpc/spend.cpp
+++ b/src/wallet/rpc/spend.cpp
@@ -1407,7 +1407,7 @@ RPCHelpMan sendall()
}
CAmount output_amounts_claimed{0};
- for (CTxOut out : rawTx.vout) {
+ for (const CTxOut& out : rawTx.vout) {
output_amounts_claimed += out.nValue;
}
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 8d40846332..40d5ecd755 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -1788,7 +1788,7 @@ std::map<CKeyID, CKey> DescriptorScriptPubKeyMan::GetKeys() const
AssertLockHeld(cs_desc_man);
if (m_storage.HasEncryptionKeys() && !m_storage.IsLocked()) {
KeyMap keys;
- for (auto key_pair : m_map_crypted_keys) {
+ for (const auto& key_pair : m_map_crypted_keys) {
const CPubKey& pubkey = key_pair.second.first;
const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
CKey key;
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index d6362c1f14..001acd04e2 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -569,8 +569,12 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
if (!coin_control.GetExternalOutput(outpoint, txout)) {
return std::nullopt;
}
+ }
+
+ if (input_bytes == -1) {
input_bytes = CalculateMaximumSignedInputSize(txout, outpoint, &coin_control.m_external_provider, &coin_control);
}
+
// If available, override calculated size with coin control specified size
if (coin_control.HasInputWeight(outpoint)) {
input_bytes = GetVirtualTransactionSize(coin_control.GetInputWeight(outpoint), 0, 0);
@@ -1127,12 +1131,16 @@ bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet,
wallet.chain().findCoins(coins);
for (const CTxIn& txin : tx.vin) {
- // if it's not in the wallet and corresponding UTXO is found than select as external output
const auto& outPoint = txin.prevout;
- if (wallet.mapWallet.find(outPoint.hash) == wallet.mapWallet.end() && !coins[outPoint].out.IsNull()) {
- coinControl.SelectExternal(outPoint, coins[outPoint].out);
- } else {
+ if (wallet.IsMine(outPoint)) {
+ // The input was found in the wallet, so select as internal
coinControl.Select(outPoint);
+ } else if (coins[outPoint].out.IsNull()) {
+ error = _("Unable to find UTXO for external input");
+ return false;
+ } else {
+ // The input was not in the wallet, but is in the UTXO set, so select as external
+ coinControl.SelectExternal(outPoint, coins[outPoint].out);
}
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 553adcc3a2..de787ae421 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1428,6 +1428,19 @@ bool CWallet::IsMine(const CTransaction& tx) const
return false;
}
+isminetype CWallet::IsMine(const COutPoint& outpoint) const
+{
+ AssertLockHeld(cs_wallet);
+ auto wtx = GetWalletTx(outpoint.hash);
+ if (!wtx) {
+ return ISMINE_NO;
+ }
+ if (outpoint.n >= wtx->tx->vout.size()) {
+ return ISMINE_NO;
+ }
+ return IsMine(wtx->tx->vout[outpoint.n]);
+}
+
bool CWallet::IsFromMe(const CTransaction& tx) const
{
return (GetDebit(tx, ISMINE_ALL) > 0);
@@ -3460,7 +3473,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans()
const UniValue& descriptor_vals = find_value(signer_res, internal ? "internal" : "receive");
if (!descriptor_vals.isArray()) throw std::runtime_error(std::string(__func__) + ": Unexpected result");
for (const UniValue& desc_val : descriptor_vals.get_array().getValues()) {
- std::string desc_str = desc_val.getValStr();
+ const std::string& desc_str = desc_val.getValStr();
FlatSigningProvider keys;
std::string desc_error;
std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, desc_error, false);
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 4fc41b2f53..3a46d0a987 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -685,6 +685,7 @@ public:
CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
isminetype IsMine(const CTxOut& txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool IsMine(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ isminetype IsMine(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/** should probably be renamed to IsRelevantToMe */
bool IsFromMe(const CTransaction& tx) const;
CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 8afd3f416d..0d85652c0c 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -856,18 +856,18 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
}
// Set the descriptor caches
- for (auto desc_cache_pair : wss.m_descriptor_caches) {
+ for (const auto& desc_cache_pair : wss.m_descriptor_caches) {
auto spk_man = pwallet->GetScriptPubKeyMan(desc_cache_pair.first);
assert(spk_man);
((DescriptorScriptPubKeyMan*)spk_man)->SetCache(desc_cache_pair.second);
}
// Set the descriptor keys
- for (auto desc_key_pair : wss.m_descriptor_keys) {
+ for (const auto& desc_key_pair : wss.m_descriptor_keys) {
auto spk_man = pwallet->GetScriptPubKeyMan(desc_key_pair.first.first);
((DescriptorScriptPubKeyMan*)spk_man)->AddKey(desc_key_pair.first.second, desc_key_pair.second);
}
- for (auto desc_key_pair : wss.m_descriptor_crypt_keys) {
+ for (const auto& desc_key_pair : wss.m_descriptor_crypt_keys) {
auto spk_man = pwallet->GetScriptPubKeyMan(desc_key_pair.first.first);
((DescriptorScriptPubKeyMan*)spk_man)->AddCryptedKey(desc_key_pair.first.second, desc_key_pair.second.first, desc_key_pair.second.second);
}
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index cf9ad3f458..5a870de6c7 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -408,7 +408,7 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin!
outputs = { self.nodes[0].getnewaddress() : 1.0}
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
- assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx)
+ assert_raises_rpc_error(-4, "Unable to find UTXO for external input", self.nodes[2].fundrawtransaction, rawtx)
def test_fee_p2pkh(self):
"""Compare fee of a standard pubkeyhash transaction."""
@@ -1079,17 +1079,28 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[2].createwallet("test_weight_calculation")
wallet = self.nodes[2].get_wallet_rpc("test_weight_calculation")
- addr = wallet.getnewaddress()
- txid = self.nodes[0].sendtoaddress(addr, 5)
+ addr = wallet.getnewaddress(address_type="bech32")
+ ext_addr = self.nodes[0].getnewaddress(address_type="bech32")
+ txid = self.nodes[0].send([{addr: 5}, {ext_addr: 5}])["txid"]
vout = find_vout_for_address(self.nodes[0], txid, addr)
+ ext_vout = find_vout_for_address(self.nodes[0], txid, ext_addr)
- self.nodes[0].sendtoaddress(wallet.getnewaddress(), 5)
+ self.nodes[0].sendtoaddress(wallet.getnewaddress(address_type="bech32"), 5)
self.generate(self.nodes[0], 1)
- rawtx = wallet.createrawtransaction([{'txid': txid, 'vout': vout}], [{self.nodes[0].getnewaddress(): 9.999}])
- fundedtx = wallet.fundrawtransaction(rawtx, {'fee_rate': 10})
+ rawtx = wallet.createrawtransaction([{'txid': txid, 'vout': vout}], [{self.nodes[0].getnewaddress(address_type="bech32"): 8}])
+ fundedtx = wallet.fundrawtransaction(rawtx, {'fee_rate': 10, "change_type": "bech32"})
# with 71-byte signatures we should expect following tx size
- tx_size = 10 + 41*2 + 31*2 + (2 + 107*2)/4
+ # tx overhead (10) + 2 inputs (41 each) + 2 p2wpkh (31 each) + (segwit marker and flag (2) + 2 p2wpkh 71 byte sig witnesses (107 each)) / witness scaling factor (4)
+ tx_size = ceil(10 + 41*2 + 31*2 + (2 + 107*2)/4)
+ assert_equal(fundedtx['fee'] * COIN, tx_size * 10)
+
+ # Using the other output should have 72 byte sigs
+ rawtx = wallet.createrawtransaction([{'txid': txid, 'vout': ext_vout}], [{self.nodes[0].getnewaddress(): 13}])
+ ext_desc = self.nodes[0].getaddressinfo(ext_addr)["desc"]
+ fundedtx = wallet.fundrawtransaction(rawtx, {'fee_rate': 10, "change_type": "bech32", "solving_data": {"descriptors": [ext_desc]}})
+ # tx overhead (10) + 3 inputs (41 each) + 2 p2wpkh(31 each) + (segwit marker and flag (2) + 2 p2wpkh 71 bytes sig witnesses (107 each) + p2wpkh 72 byte sig witness (108)) / witness scaling factor (4)
+ tx_size = ceil(10 + 41*3 + 31*2 + (2 + 107*2 + 108)/4)
assert_equal(fundedtx['fee'] * COIN, tx_size * 10)
self.nodes[2].unloadwallet("test_weight_calculation")