diff --git a/src/.bear-tidy-config b/src/.bear-tidy-config index fd12f3d130ba..3512e59a781b 100644 --- a/src/.bear-tidy-config +++ b/src/.bear-tidy-config @@ -12,6 +12,8 @@ "src/leveldb", "src/minisketch", "src/univalue", + "src/bench/nanobench.cpp", + "src/bench/nanobench.h", "src/secp256k1" ] }, diff --git a/src/.clang-tidy b/src/.clang-tidy index bb3f4194760c..b363353d2fc4 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -4,6 +4,7 @@ bugprone-argument-comment, bugprone-use-after-move, misc-unused-using-decls, modernize-use-default-member-init, +modernize-use-emplace, modernize-use-nullptr, performance-for-range-copy, performance-move-const-arg, diff --git a/src/addrdb.cpp b/src/addrdb.cpp index 83bc6192ff7b..723681765530 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -182,10 +182,10 @@ void ReadFromStream(AddrMan& addr, CDataStream& ssPeers) DeserializeDB(ssPeers, addr, false); } -std::optional LoadAddrman(const NetGroupManager& netgroupman, const ArgsManager& args, std::unique_ptr& addrman) +util::Result> LoadAddrman(const NetGroupManager& netgroupman, const ArgsManager& args) { auto check_addrman = std::clamp(args.GetIntArg("-checkaddrman", DEFAULT_ADDRMAN_CONSISTENCY_CHECKS), 0, 1000000); - addrman = std::make_unique(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman); + auto addrman{std::make_unique(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman)}; const auto start{SteadyClock::now()}; const auto path_addr{gArgs.GetDataDirNet() / "peers.dat"}; @@ -208,19 +208,17 @@ std::optional LoadAddrman(const NetGroupManager& netgroupman, con DumpPeerAddresses(args, *addrman); } catch (const InvalidAddrManVersionError&) { if (!RenameOver(path_addr, (fs::path)path_addr + ".bak")) { - addrman = nullptr; - return strprintf(_("Failed to rename invalid peers.dat file. Please move or delete it and try again.")); + return util::Error{strprintf(_("Failed to rename invalid peers.dat file. Please move or delete it and try again."))}; } // Addrman can be in an inconsistent state after failure, reset it addrman = std::make_unique(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman); LogPrintf("Creating new peers.dat because the file version was not compatible (%s). Original backed up to peers.dat.bak\n", fs::quoted(fs::PathToString(path_addr))); DumpPeerAddresses(args, *addrman); } catch (const std::exception& e) { - addrman = nullptr; - return strprintf(_("Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start."), - e.what(), PACKAGE_BUGREPORT, fs::quoted(fs::PathToString(path_addr))); + return util::Error{strprintf(_("Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start."), + e.what(), PACKAGE_BUGREPORT, fs::quoted(fs::PathToString(path_addr)))}; } - return std::nullopt; + return addrman; // std::move should be unneccessary but is temporarily needed to work around clang bug (https://github.com/bitcoin/bitcoin/pull/25977#issuecomment-1561270092) } void DumpAnchors(const fs::path& anchors_db_path, const std::vector& anchors) diff --git a/src/addrdb.h b/src/addrdb.h index 911b791b7170..a5958409efec 100644 --- a/src/addrdb.h +++ b/src/addrdb.h @@ -9,6 +9,7 @@ #include #include // For banmap_t #include +#include #include #include @@ -50,7 +51,7 @@ class CBanDB }; /** Returns an error string on failure */ -std::optional LoadAddrman(const NetGroupManager& netgroupman, const ArgsManager& args, std::unique_ptr& addrman); +util::Result> LoadAddrman(const NetGroupManager& netgroupman, const ArgsManager& args); /** * Dump the anchor IP address database (anchors.dat) diff --git a/src/bench/wallet_loading.cpp b/src/bench/wallet_loading.cpp index a81d79936e5b..37f2c90ea281 100644 --- a/src/bench/wallet_loading.cpp +++ b/src/bench/wallet_loading.cpp @@ -46,8 +46,8 @@ static void BenchUnloadWallet(std::shared_ptr&& wallet) static void AddTx(CWallet& wallet) { CMutableTransaction mtx; - mtx.vout.push_back({COIN, GetScriptForDestination(*Assert(wallet.GetNewDestination("")))}); - mtx.vin.push_back(CTxIn()); + mtx.vout.emplace_back(COIN, GetScriptForDestination(*Assert(wallet.GetNewDestination("")))); + mtx.vin.emplace_back(); wallet.AddToWallet(MakeTransactionRef(mtx), TxStateInactive{}); } diff --git a/src/external_signer.cpp b/src/external_signer.cpp index 9659cc1a06dc..cda34a14fd2f 100644 --- a/src/external_signer.cpp +++ b/src/external_signer.cpp @@ -54,7 +54,7 @@ bool ExternalSigner::Enumerate(const std::string& command, std::vector NetPermissions::ToStrings(NetPermissionFlags flags) { std::vector strings; - if (NetPermissions::HasFlag(flags, NetPermissionFlags::BloomFilter)) strings.push_back("bloomfilter"); - if (NetPermissions::HasFlag(flags, NetPermissionFlags::NoBan)) strings.push_back("noban"); - if (NetPermissions::HasFlag(flags, NetPermissionFlags::ForceRelay)) strings.push_back("forcerelay"); - if (NetPermissions::HasFlag(flags, NetPermissionFlags::Relay)) strings.push_back("relay"); - if (NetPermissions::HasFlag(flags, NetPermissionFlags::Mempool)) strings.push_back("mempool"); - if (NetPermissions::HasFlag(flags, NetPermissionFlags::Download)) strings.push_back("download"); - if (NetPermissions::HasFlag(flags, NetPermissionFlags::Addr)) strings.push_back("addr"); + if (NetPermissions::HasFlag(flags, NetPermissionFlags::BloomFilter)) strings.emplace_back("bloomfilter"); + if (NetPermissions::HasFlag(flags, NetPermissionFlags::NoBan)) strings.emplace_back("noban"); + if (NetPermissions::HasFlag(flags, NetPermissionFlags::ForceRelay)) strings.emplace_back("forcerelay"); + if (NetPermissions::HasFlag(flags, NetPermissionFlags::Relay)) strings.emplace_back("relay"); + if (NetPermissions::HasFlag(flags, NetPermissionFlags::Mempool)) strings.emplace_back("mempool"); + if (NetPermissions::HasFlag(flags, NetPermissionFlags::Download)) strings.emplace_back("download"); + if (NetPermissions::HasFlag(flags, NetPermissionFlags::Addr)) strings.emplace_back("addr"); return strings; } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 21a3f7102bdb..7642ca1e4ebb 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2799,7 +2799,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& // and we want it right after the last block so they don't // wait for other stuff first. std::vector vInv; - vInv.push_back(CInv(MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash())); + vInv.emplace_back(MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash()); m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::INV, vInv)); peer.m_continuation_block.SetNull(); } @@ -3199,7 +3199,7 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, c // Can't download any more from this peer break; } - vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); + vGetData.emplace_back(MSG_BLOCK, pindex->GetBlockHash()); BlockRequested(pfrom.GetId(), *pindex); LogPrint(BCLog::NET, "Requesting block %s from peer=%d\n", pindex->GetBlockHash().ToString(), pfrom.GetId()); @@ -4616,7 +4616,7 @@ void PeerManagerImpl::ProcessMessage( const auto send_headers = [this /* for m_connman */, &hashStop, &pindex, &nodestate, &pfrom, &msgMaker](auto msg_type_internal, auto& v_headers, auto callback) { int nLimit = GetHeadersLimit(pfrom, msg_type_internal == NetMsgType::HEADERS2); for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex)) { - v_headers.push_back(callback(pindex)); + v_headers.emplace_back(callback(pindex)); if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) break; @@ -6167,14 +6167,14 @@ bool PeerManagerImpl::SendMessages(CNode* pto) } if (fFoundStartingHeader) { // add this to the headers message - vHeaders.push_back(pindex->GetBlockHeader()); + vHeaders.emplace_back(pindex->GetBlockHeader()); } else if (PeerHasHeader(&state, pindex)) { continue; // keep looking for the first new block } else if (pindex->pprev == nullptr || PeerHasHeader(&state, pindex->pprev) || isPrevDevnetGenesisBlock) { // Peer doesn't have this header but they do have the prior one. // Start sending headers. fFoundStartingHeader = true; - vHeaders.push_back(pindex->GetBlockHeader()); + vHeaders.emplace_back(pindex->GetBlockHeader()); } else { // Peer doesn't have this header or the prior one -- nothing will // connect, so bail out. @@ -6282,7 +6282,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) // Add blocks for (const uint256& hash : peer->m_blocks_for_inv_relay) { - vInv.push_back(CInv(MSG_BLOCK, hash)); + vInv.emplace_back(MSG_BLOCK, hash); if (vInv.size() == MAX_INV_SZ) { m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv)); vInv.clear(); @@ -6527,7 +6527,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) NodeId staller = -1; FindNextBlocksToDownload(*peer, MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); for (const CBlockIndex *pindex : vToDownload) { - vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); + vGetData.emplace_back(MSG_BLOCK, pindex->GetBlockHash()); BlockRequested(pto->GetId(), *pindex); LogPrint(BCLog::NET, "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), pindex->nHeight, pto->GetId()); diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index d6606442475a..537429f8d56c 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -331,7 +331,7 @@ bool BlockManager::WriteBlockIndexDB() std::vector> vFiles; vFiles.reserve(m_dirty_fileinfo.size()); for (std::set::iterator it = m_dirty_fileinfo.begin(); it != m_dirty_fileinfo.end();) { - vFiles.push_back(std::make_pair(*it, &m_blockfile_info[*it])); + vFiles.emplace_back(*it, &m_blockfile_info[*it]); m_dirty_fileinfo.erase(it++); } std::vector vBlocks; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 1c5596baafb7..35626bb2cfa5 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -184,7 +184,7 @@ class PeerIdViewDelegate : public QStyledItemDelegate bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut, const WalletModel* wallet_model) { std::vector< std::vector > stack; - stack.push_back(std::vector()); + stack.emplace_back(); enum CmdParseState { @@ -212,7 +212,7 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes } // Make sure stack is not empty before adding something if (stack.empty()) { - stack.push_back(std::vector()); + stack.emplace_back(); } stack.back().push_back(strArg); }; @@ -221,7 +221,7 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes if (nDepthInsideSensitive) { if (!--nDepthInsideSensitive) { assert(filter_begin_pos); - filter_ranges.push_back(std::make_pair(filter_begin_pos, chpos)); + filter_ranges.emplace_back(filter_begin_pos, chpos); filter_begin_pos = 0; } } @@ -321,7 +321,7 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes if (nDepthInsideSensitive) { ++nDepthInsideSensitive; } - stack.push_back(std::vector()); + stack.emplace_back(); } // don't allow commands after executed commands on baselevel diff --git a/src/rest.cpp b/src/rest.cpp index 6ebe50b4411e..70c61e40fe25 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -761,7 +761,7 @@ static bool rest_getutxos(const CoreContext& context, HTTPRequest* req, const st return RESTERR(req, HTTP_BAD_REQUEST, "Parse error"); txid.SetHex(strTxid); - vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput)); + vOutPoints.emplace_back(txid, (uint32_t)nOutput); } if (vOutPoints.size() > 0) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 1803294f7b3c..38601153692b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2192,7 +2192,7 @@ static RPCHelpMan getblockstats() CAmount feerate = tx_size ? txfee / tx_size : 0; if (do_feerate_percentiles) { - feerate_array.emplace_back(std::make_pair(feerate, tx_size)); + feerate_array.emplace_back(feerate, tx_size); } maxfeerate = std::max(maxfeerate, feerate); minfeerate = std::min(minfeerate, feerate); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 7a0dd1f71e05..6f4a94c9b7c2 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1650,10 +1650,10 @@ static RPCHelpMan createpsbt() PartiallySignedTransaction psbtx; psbtx.tx = rawTx; for (unsigned int i = 0; i < rawTx.vin.size(); ++i) { - psbtx.inputs.push_back(PSBTInput()); + psbtx.inputs.emplace_back(); } for (unsigned int i = 0; i < rawTx.vout.size(); ++i) { - psbtx.outputs.push_back(PSBTOutput()); + psbtx.outputs.emplace_back(); } // Serialize the PSBT @@ -1707,10 +1707,10 @@ static RPCHelpMan converttopsbt() PartiallySignedTransaction psbtx; psbtx.tx = tx; for (unsigned int i = 0; i < tx.vin.size(); ++i) { - psbtx.inputs.push_back(PSBTInput()); + psbtx.inputs.emplace_back(); } for (unsigned int i = 0; i < tx.vout.size(); ++i) { - psbtx.outputs.push_back(PSBTOutput()); + psbtx.outputs.emplace_back(); } // Serialize the PSBT diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 3889e09aa9e2..ab8a4da314a0 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -87,7 +87,7 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& std::vector > vCommands; for (const auto& entry : mapCommands) - vCommands.push_back(make_pair(entry.second.front()->category + entry.first, entry.second.front())); + vCommands.emplace_back(entry.second.front()->category + entry.first, entry.second.front()); sort(vCommands.begin(), vCommands.end()); JSONRPCRequest jreq = helpreq; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 55ab8e248c41..2622862f4d67 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -137,7 +137,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator case TxoutType::SCRIPTHASH: { uint160 h160{vSolutions[0]}; if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) { - ret.push_back(std::vector(scriptRet.begin(), scriptRet.end())); + ret.emplace_back(scriptRet.begin(), scriptRet.end()); return true; } // Could not find redeemScript, add to missing @@ -146,7 +146,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator } case TxoutType::MULTISIG: { size_t required = vSolutions.front()[0]; - ret.push_back(valtype()); // workaround CHECKMULTISIG bug + ret.emplace_back(); // workaround CHECKMULTISIG bug for (size_t i = 1; i < vSolutions.size() - 1; ++i) { CPubKey pubkey = CPubKey(vSolutions[i]); // We need to always call CreateSig in order to fill sigdata with all @@ -160,7 +160,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator } bool ok = ret.size() == required + 1; for (size_t i = 0; i + ret.size() < required + 1; ++i) { - ret.push_back(valtype()); + ret.emplace_back(); } return ok; } @@ -207,7 +207,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato } if (P2SH) { - result.push_back(std::vector(subscript.begin(), subscript.end())); + result.emplace_back(subscript.begin(), subscript.end()); } sigdata.scriptSig = PushAll(result); diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 2efb321266bb..1bed107afe7f 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -97,8 +97,8 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test: reset addrman and test AddrMan::Add multiple addresses works as expected addrman = std::make_unique(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)); std::vector vAddr; - vAddr.push_back(CAddress(ResolveService("250.1.1.3", 8333), NODE_NONE)); - vAddr.push_back(CAddress(ResolveService("250.1.1.4", 8333), NODE_NONE)); + vAddr.emplace_back(ResolveService("250.1.1.3", 8333), NODE_NONE); + vAddr.emplace_back(ResolveService("250.1.1.4", 8333), NODE_NONE); BOOST_CHECK(addrman->Add(vAddr, source)); BOOST_CHECK(addrman->Size() >= 1); } diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 3a52630a5d56..e3a71c963f43 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -29,7 +29,7 @@ struct TestVector { explicit TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {} TestVector& operator()(std::string pub, std::string prv, unsigned int nChild) { - vDerive.push_back(TestDerivation()); + vDerive.emplace_back(); TestDerivation &der = vDerive.back(); der.pub = pub; der.prv = prv; diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 3c77fed9bd8f..e950061d1d6e 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -1096,9 +1096,9 @@ class V2TransportTester bool reject{false}; auto msg = m_transport.GetReceivedMessage({}, reject); if (reject) { - ret.push_back(std::nullopt); + ret.emplace_back(std::nullopt); } else { - ret.push_back(std::move(msg)); + ret.emplace_back(std::move(msg)); } progress = true; } diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 7638ab309fe3..a0e2626f8f78 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -416,11 +416,11 @@ BOOST_AUTO_TEST_CASE(rpc_getblockstats_calculate_percentiles_by_size) CAmount result[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 }; for (int64_t i = 0; i < 100; i++) { - feerates.emplace_back(std::make_pair(1 ,1)); + feerates.emplace_back(1 ,1); } for (int64_t i = 0; i < 100; i++) { - feerates.emplace_back(std::make_pair(2 ,1)); + feerates.emplace_back(2 ,1); } CalculatePercentilesBySize(result, feerates, total_size); @@ -435,11 +435,11 @@ BOOST_AUTO_TEST_CASE(rpc_getblockstats_calculate_percentiles_by_size) CAmount result2[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 }; feerates.clear(); - feerates.emplace_back(std::make_pair(1, 9)); - feerates.emplace_back(std::make_pair(2 , 16)); //10th + 25th percentile - feerates.emplace_back(std::make_pair(4 ,50)); //50th + 75th percentile - feerates.emplace_back(std::make_pair(5 ,10)); - feerates.emplace_back(std::make_pair(9 ,15)); // 90th percentile + feerates.emplace_back(1, 9); + feerates.emplace_back(2 , 16); //10th + 25th percentile + feerates.emplace_back(4 ,50); //50th + 75th percentile + feerates.emplace_back(5 ,10); + feerates.emplace_back(9 ,15); // 90th percentile CalculatePercentilesBySize(result2, feerates, total_size); @@ -454,12 +454,12 @@ BOOST_AUTO_TEST_CASE(rpc_getblockstats_calculate_percentiles_by_size) CAmount result3[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 }; feerates.clear(); - feerates.emplace_back(std::make_pair(1, 9)); - feerates.emplace_back(std::make_pair(2 , 11)); // 10th percentile - feerates.emplace_back(std::make_pair(2 , 5)); // 25th percentile - feerates.emplace_back(std::make_pair(4 ,50)); //50th + 75th percentile - feerates.emplace_back(std::make_pair(5 ,10)); - feerates.emplace_back(std::make_pair(9 ,15)); // 90th percentile + feerates.emplace_back(1, 9); + feerates.emplace_back(2 , 11); // 10th percentile + feerates.emplace_back(2 , 5); // 25th percentile + feerates.emplace_back(4 ,50); //50th + 75th percentile + feerates.emplace_back(5 ,10); + feerates.emplace_back(9 ,15); // 90th percentile CalculatePercentilesBySize(result3, feerates, total_size); @@ -474,11 +474,11 @@ BOOST_AUTO_TEST_CASE(rpc_getblockstats_calculate_percentiles_by_size) CAmount result4[NUM_GETBLOCKSTATS_PERCENTILES] = { 0 }; feerates.clear(); - feerates.emplace_back(std::make_pair(1, 100)); - feerates.emplace_back(std::make_pair(2, 1)); - feerates.emplace_back(std::make_pair(3, 1)); - feerates.emplace_back(std::make_pair(3, 1)); - feerates.emplace_back(std::make_pair(999999, 1)); + feerates.emplace_back(1, 100); + feerates.emplace_back(2, 1); + feerates.emplace_back(3, 1); + feerates.emplace_back(3, 1); + feerates.emplace_back(999999, 1); CalculatePercentilesBySize(result4, feerates, total_size); diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp index ad12c4656106..9bd9c7942043 100644 --- a/src/test/settings_tests.cpp +++ b/src/test/settings_tests.cpp @@ -119,16 +119,16 @@ static void CheckValues(const util::Settings& settings, const std::string& singl BOOST_AUTO_TEST_CASE(Simple) { util::Settings settings; - settings.command_line_options["name"].push_back("val1"); - settings.command_line_options["name"].push_back("val2"); - settings.ro_config["section"]["name"].push_back(2); + settings.command_line_options["name"].emplace_back("val1"); + settings.command_line_options["name"].emplace_back("val2"); + settings.ro_config["section"]["name"].emplace_back(2); // The last given arg takes precedence when specified via commandline. CheckValues(settings, R"("val2")", R"(["val1","val2",2])"); util::Settings settings2; - settings2.ro_config["section"]["name"].push_back("val2"); - settings2.ro_config["section"]["name"].push_back("val3"); + settings2.ro_config["section"]["name"].emplace_back("val2"); + settings2.ro_config["section"]["name"].emplace_back("val3"); // The first given arg takes precedence when specified via config file. CheckValues(settings2, R"("val2")", R"(["val2","val3"])"); @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(Simple) BOOST_AUTO_TEST_CASE(NullOverride) { util::Settings settings; - settings.command_line_options["name"].push_back("value"); + settings.command_line_options["name"].emplace_back("value"); BOOST_CHECK_EQUAL(R"("value")", GetSetting(settings, "section", "name", false, false, false).write().c_str()); settings.forced_settings["name"] = {}; BOOST_CHECK_EQUAL(R"(null)", GetSetting(settings, "section", "name", false, false, false).write().c_str()); @@ -202,11 +202,11 @@ BOOST_FIXTURE_TEST_CASE(Merge, MergeTestingSetup) std::vector& dest) { if (action == SET || action == SECTION_SET) { for (int i = 0; i < 2; ++i) { - dest.push_back(value_prefix + ToString(++value_suffix)); + dest.emplace_back(value_prefix + ToString(++value_suffix)); desc += " " + name_prefix + name + "=" + dest.back().get_str(); } } else if (action == NEGATE || action == SECTION_NEGATE) { - dest.push_back(false); + dest.emplace_back(false); desc += " " + name_prefix + "no" + name; } }; diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index f1d8e6d0ad90..b765f9a808db 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -96,7 +96,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) int ins = (InsecureRandBits(2)) + 1; int outs = fSingle ? ins : (InsecureRandBits(2)) + 1; for (int in = 0; in < ins; in++) { - tx.vin.push_back(CTxIn()); + tx.vin.emplace_back(); CTxIn &txin = tx.vin.back(); txin.prevout.hash = InsecureRand256(); txin.prevout.n = InsecureRandBits(2); @@ -104,7 +104,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) txin.nSequence = (InsecureRandBool()) ? InsecureRand32() : std::numeric_limits::max(); } for (int out = 0; out < outs; out++) { - tx.vout.push_back(CTxOut()); + tx.vout.emplace_back(); CTxOut &txout = tx.vout.back(); txout.nValue = InsecureRandRange(100000000); RandomScript(txout.scriptPubKey); diff --git a/src/test/txpackage_tests.cpp b/src/test/txpackage_tests.cpp index 07bfc64eee75..c16a5eaf6a9e 100644 --- a/src/test/txpackage_tests.cpp +++ b/src/test/txpackage_tests.cpp @@ -160,9 +160,9 @@ BOOST_FIXTURE_TEST_CASE(noncontextual_package_tests, TestChain100NoDIP0001Setup) auto parent = MakeTransactionRef(CreateValidMempoolTransaction(m_coinbase_txns[i + 1], 0, 0, coinbaseKey, spk, CAmount(48 * COIN), false)); package.emplace_back(parent); - child.vin.push_back(CTxIn(COutPoint(parent->GetHash(), 0))); + child.vin.emplace_back(COutPoint(parent->GetHash(), 0)); } - child.vout.push_back(CTxOut(47 * COIN, spk2)); + child.vout.emplace_back(47 * COIN, spk2); // The child must be in the package. BOOST_CHECK(!IsChildWithParents(package)); @@ -187,20 +187,20 @@ BOOST_FIXTURE_TEST_CASE(noncontextual_package_tests, TestChain100NoDIP0001Setup) // 2 Parents and 1 Child where one parent depends on the other. { CMutableTransaction mtx_parent; - mtx_parent.vin.push_back(CTxIn(COutPoint(m_coinbase_txns[0]->GetHash(), 0))); - mtx_parent.vout.push_back(CTxOut(20 * COIN, spk)); - mtx_parent.vout.push_back(CTxOut(20 * COIN, spk2)); + mtx_parent.vin.emplace_back(COutPoint(m_coinbase_txns[0]->GetHash(), 0)); + mtx_parent.vout.emplace_back(20 * COIN, spk); + mtx_parent.vout.emplace_back(20 * COIN, spk2); CTransactionRef tx_parent = MakeTransactionRef(mtx_parent); CMutableTransaction mtx_parent_also_child; - mtx_parent_also_child.vin.push_back(CTxIn(COutPoint(tx_parent->GetHash(), 0))); - mtx_parent_also_child.vout.push_back(CTxOut(20 * COIN, spk)); + mtx_parent_also_child.vin.emplace_back(COutPoint(tx_parent->GetHash(), 0)); + mtx_parent_also_child.vout.emplace_back(20 * COIN, spk); CTransactionRef tx_parent_also_child = MakeTransactionRef(mtx_parent_also_child); CMutableTransaction mtx_child; - mtx_child.vin.push_back(CTxIn(COutPoint(tx_parent->GetHash(), 1))); - mtx_child.vin.push_back(CTxIn(COutPoint(tx_parent_also_child->GetHash(), 0))); - mtx_child.vout.push_back(CTxOut(39 * COIN, spk)); + mtx_child.vin.emplace_back(COutPoint(tx_parent->GetHash(), 1)); + mtx_child.vin.emplace_back(COutPoint(tx_parent_also_child->GetHash(), 0)); + mtx_child.vout.emplace_back(39 * COIN, spk); CTransactionRef tx_child = MakeTransactionRef(mtx_child); PackageValidationState state; @@ -282,7 +282,7 @@ BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100NoDIP0001Setup) } // Child with missing parent. - mtx_child.vin.push_back(CTxIn(COutPoint(package_unrelated[0]->GetHash(), 0))); + mtx_child.vin.emplace_back(COutPoint(package_unrelated[0]->GetHash(), 0)); Package package_missing_parent; package_missing_parent.push_back(tx_parent); package_missing_parent.push_back(MakeTransactionRef(mtx_child)); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 8a96cb0c9ba4..e8af3b7627b0 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -655,7 +655,7 @@ std::vector TestChainSetup::PopulateMempool(FastRandomContext& for (size_t n{0}; n < num_inputs; ++n) { if (unspent_prevouts.empty()) break; const auto& [prevout, amount] = unspent_prevouts.front(); - mtx.vin.push_back(CTxIn(prevout, CScript())); + mtx.vin.emplace_back(prevout, CScript()); total_in += amount; unspent_prevouts.pop_front(); } @@ -664,7 +664,7 @@ std::vector TestChainSetup::PopulateMempool(FastRandomContext& const CAmount amount_per_output = (total_in - 1000) / num_outputs; for (size_t n{0}; n < num_outputs; ++n) { CScript spk = CScript() << CScriptNum(num_transactions + n); - mtx.vout.push_back(CTxOut(amount_per_output, spk)); + mtx.vout.emplace_back(amount_per_output, spk); } CTransactionRef ptx = MakeTransactionRef(mtx); mempool_transactions.push_back(ptx); @@ -673,7 +673,7 @@ std::vector TestChainSetup::PopulateMempool(FastRandomContext& // it can be used to build a more complex transaction graph. Insert randomly into // unspent_prevouts for extra randomness in the resulting structures. for (size_t n{0}; n < num_outputs; ++n) { - unspent_prevouts.push_back(std::make_pair(COutPoint(ptx->GetHash(), n), amount_per_output)); + unspent_prevouts.emplace_back(COutPoint(ptx->GetHash(), n), amount_per_output); std::swap(unspent_prevouts.back(), unspent_prevouts[det_rand.randrange(unspent_prevouts.size())]); } } @@ -701,8 +701,8 @@ void TestChainSetup::MockMempoolMinFee(const CFeeRate& target_feerate) // Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to // achieve the exact target feerate. CMutableTransaction mtx = CMutableTransaction(); - mtx.vin.push_back(CTxIn{COutPoint{g_insecure_rand_ctx.rand256(), 0}}); - mtx.vout.push_back(CTxOut(1 * COIN, GetScriptForDestination(ScriptHash(CScript() << OP_TRUE)))); + mtx.vin.emplace_back(COutPoint{g_insecure_rand_ctx.rand256(), 0}); + mtx.vout.emplace_back(1 * COIN, GetScriptForDestination(ScriptHash(CScript() << OP_TRUE))); const auto tx{MakeTransactionRef(mtx)}; LockPoints lp; // The new mempool min feerate is equal to the removed package's feerate + incremental feerate. diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp index b305fbdc6040..f9234a2a4618 100644 --- a/src/test/util/txmempool.cpp +++ b/src/test/util/txmempool.cpp @@ -20,8 +20,8 @@ CTxMemPool::Options MemPoolOptionsForTest(const NodeContext& node) // chainparams.DefaultConsistencyChecks for tests .check_ratio = 1, }; - const auto err{ApplyArgsManOptions(*node.args, ::Params(), mempool_opts)}; - Assert(!err); + const auto result{ApplyArgsManOptions(*node.args, ::Params(), mempool_opts)}; + Assert(result); return mempool_opts; } */ diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 2da64caf6576..f78a8e0c264a 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1037,9 +1037,9 @@ BOOST_AUTO_TEST_CASE(test_FormatParagraph) BOOST_AUTO_TEST_CASE(test_FormatSubVersion) { std::vector comments; - comments.push_back(std::string("comment1")); + comments.emplace_back("comment1"); std::vector comments2; - comments2.push_back(std::string("comment1")); + comments2.emplace_back("comment1"); comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector()),std::string("/Test:9.99.0/")); BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:9.99.0(comment1)/")); diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp index 3ddf3390615f..53987ae856fa 100644 --- a/src/test/util_threadnames_tests.cpp +++ b/src/test/util_threadnames_tests.cpp @@ -35,7 +35,7 @@ std::set RenameEnMasse(int num_threads) }; for (int i = 0; i < num_threads; ++i) { - threads.push_back(std::thread(RenameThisThread, i)); + threads.emplace_back(RenameThisThread, i); } for (std::thread& thread : threads) thread.join(); diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp index 88867be2e75d..2c5c3bf3e6a3 100644 --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -116,7 +116,7 @@ std::shared_ptr MinerTestingSetup::BadBlock(const uint256& prev_ha auto pblock = Block(prev_hash); CMutableTransaction coinbase_spend; - coinbase_spend.vin.push_back(CTxIn(COutPoint(pblock->vtx[0]->GetHash(), 0), CScript(), 0)); + coinbase_spend.vin.emplace_back(COutPoint(pblock->vtx[0]->GetHash(), 0), CScript(), 0); coinbase_spend.vout.push_back(pblock->vtx[0]->vout[0]); CTransactionRef tx = MakeTransactionRef(coinbase_spend); diff --git a/src/util/result.h b/src/util/result.h index 972b1aada013..b99995c7e562 100644 --- a/src/util/result.h +++ b/src/util/result.h @@ -31,16 +31,19 @@ struct Error { //! `std::optional` can be updated to return `util::Result` and return //! error strings usually just replacing `return std::nullopt;` with `return //! util::Error{error_string};`. -template +template class Result { private: + using T = std::conditional_t, std::monostate, M>; + std::variant m_variant; template friend bilingual_str ErrorString(const Result& result); public: + Result() : m_variant{std::in_place_index_t<1>{}, std::monostate{}} {} // constructor for void Result(T obj) : m_variant{std::in_place_index_t<1>{}, std::move(obj)} {} Result(Error error) : m_variant{std::in_place_index_t<0>{}, std::move(error.message)} {} diff --git a/src/validation.cpp b/src/validation.cpp index 2a16f339b631..e22ffb3829b9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2226,8 +2226,6 @@ class WarningBitsConditionChecker : public AbstractThresholdConditionChecker } }; -static std::array warningcache GUARDED_BY(cs_main); - static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const ChainstateManager& chainman) { unsigned int flags = SCRIPT_VERIFY_NONE; @@ -2583,7 +2581,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CTxUndo undoDummy; if (i > 0) { - blockundo.vtxundo.push_back(CTxUndo()); + blockundo.vtxundo.emplace_back(); } UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); } @@ -3008,7 +3006,7 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew) const CBlockIndex* pindex = pindexNew; for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { WarningBitsConditionChecker checker(m_chainman, bit); - ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), warningcache.at(bit)); + ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), m_chainman.m_warningcache.at(bit)); if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) { const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit); if (state == ThresholdState::ACTIVE) { @@ -6151,11 +6149,6 @@ ChainstateManager::~ChainstateManager() LOCK(::cs_main); m_versionbitscache.Clear(); - - // TODO: The warning cache should probably become non-global - for (auto& i : warningcache) { - i.clear(); - } } bool IsBIP30Repeat(const CBlockIndex& block_index) diff --git a/src/validation.h b/src/validation.h index 666773994265..8b2e1d0adb45 100644 --- a/src/validation.h +++ b/src/validation.h @@ -919,6 +919,8 @@ class ChainstateManager const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main); friend CChainState; + std::array m_warningcache GUARDED_BY(::cs_main); + public: explicit ChainstateManager(const CChainParams& chainparams) : m_chainparams{chainparams}, m_blockman{{chainparams}} { } diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp index 666516516923..c3892170501f 100644 --- a/src/wallet/rpc/backup.cpp +++ b/src/wallet/rpc/backup.cpp @@ -573,12 +573,12 @@ RPCHelpMan importwallet() fLabel = true; } } - keys.push_back(std::make_tuple(key, nTime, fLabel, strLabel)); + keys.emplace_back(key, nTime, fLabel, strLabel); } else if(IsHex(vstr[0])) { std::vector vData(ParseHex(vstr[0])); CScript script = CScript(vData.begin(), vData.end()); int64_t birth_time = ParseISO8601DateTime(vstr[1]); - scripts.push_back(std::pair(script, birth_time)); + scripts.emplace_back(script, birth_time); } } file.close(); @@ -995,7 +995,7 @@ RPCHelpMan dumpwallet() // sort time/key pairs std::vector > vKeyBirth; for (const auto& entry : mapKeyBirth) { - vKeyBirth.push_back(std::make_pair(entry.second, entry.first)); + vKeyBirth.emplace_back(entry.second, entry.first); } mapKeyBirth.clear(); std::sort(vKeyBirth.begin(), vKeyBirth.end()); diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp index 1ee0edd00e8f..d7df7f2d1876 100644 --- a/src/wallet/salvage.cpp +++ b/src/wallet/salvage.cpp @@ -103,7 +103,7 @@ bool RecoverDatabaseFile(const ArgsManager& args, const fs::path& file_path, bil warnings.push_back(Untranslated("Salvage: WARNING: Number of keys in data does not match number of values.")); break; } - salvagedData.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex))); + salvagedData.emplace_back(ParseHex(keyHex), ParseHex(valueHex)); } } diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index bfba61643130..4ca823c4ab5b 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -963,7 +963,7 @@ static util::Result CreateTransactionInternal( // works. const uint32_t nSequence{CTxIn::SEQUENCE_FINAL - 1}; for (const auto& coin : result->GetInputSet()) { - txNew.vin.push_back(CTxIn(coin.outpoint, CScript(), nSequence)); + txNew.vin.emplace_back(coin.outpoint, CScript(), nSequence); } DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetLastBlockHash(), wallet.GetLastBlockHeight()); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index a46efa651414..777dd4b07b8c 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -80,7 +80,7 @@ static void TestUnloadWallet(WalletContext& context, std::shared_ptr&& static CMutableTransaction TestSimpleSpend(const CTransaction& from, uint32_t index, const CKey& key, const CScript& pubkey) { CMutableTransaction mtx; - mtx.vout.push_back({from.vout[index].nValue - DEFAULT_TRANSACTION_MAXFEE, pubkey}); + mtx.vout.emplace_back(from.vout[index].nValue - DEFAULT_TRANSACTION_MAXFEE, pubkey); mtx.vin.push_back({CTxIn{from.GetHash(), index}}); FillableSigningProvider keystore; keystore.AddKey(key); @@ -1578,8 +1578,8 @@ BOOST_FIXTURE_TEST_CASE(wallet_sync_tx_invalid_state_test, TestChain100Setup) BOOST_ASSERT(op_dest); CMutableTransaction mtx; - mtx.vout.push_back({COIN, GetScriptForDestination(*op_dest)}); - mtx.vin.push_back(CTxIn(g_insecure_rand_ctx.rand256(), 0)); + mtx.vout.emplace_back(COIN, GetScriptForDestination(*op_dest)); + mtx.vin.emplace_back(g_insecure_rand_ctx.rand256(), 0); const auto& tx_id_to_spend = wallet.AddToWallet(MakeTransactionRef(mtx), TxStateInMempool{})->GetHash(); { @@ -1594,7 +1594,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_sync_tx_invalid_state_test, TestChain100Setup) // 2) Verify that the available balance of this new tx and the old one is updated (prev tx is marked dirty) mtx.vin.clear(); - mtx.vin.push_back(CTxIn(tx_id_to_spend, 0)); + mtx.vin.emplace_back(tx_id_to_spend, 0); wallet.transactionAddedToMempool(MakeTransactionRef(mtx), 0); const uint256& good_tx_id = mtx.GetHash(); @@ -1615,7 +1615,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_sync_tx_invalid_state_test, TestChain100Setup) // verify that we are not moving forward if the wallet cannot store it static_cast(wallet.GetDatabase()).m_pass = false; mtx.vin.clear(); - mtx.vin.push_back(CTxIn(good_tx_id, 0)); + mtx.vin.emplace_back(good_tx_id, 0); BOOST_CHECK_EXCEPTION(wallet.transactionAddedToMempool(MakeTransactionRef(mtx), 0), std::runtime_error, HasReason("DB error adding transaction to wallet, write failed"));