From 49b3d3a92a7250e80c56ff8c351cf1670e32c1a2 Mon Sep 17 00:00:00 2001 From: marcofleon Date: Thu, 31 Jul 2025 12:18:51 +0100 Subject: [PATCH 1/8] Clean up `FindTxForGetData` Adds back a comment that was unintentionally deleted in the GenTxid refactor. --- src/net_processing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 61439f71883..28e6cc7bb88 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2393,12 +2393,12 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid) { + // If a tx was in the mempool prior to the last INV for this peer, permit the request. auto txinfo{std::visit( [&](const auto& id) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex) { return m_mempool.info_for_relay(id, tx_relay.m_last_inv_sequence); }, gtxid)}; - if (txinfo.tx) { return std::move(txinfo.tx); } From 326f24472487dc7f447839136db2ccf60833e9a2 Mon Sep 17 00:00:00 2001 From: marcofleon Date: Wed, 23 Jul 2025 17:16:09 +0100 Subject: [PATCH 2/8] refactor: Convert RPCs and `merkleblock` from uint256 to Txid --- src/merkleblock.cpp | 16 ++++++------- src/merkleblock.h | 13 ++++++----- src/net_processing.cpp | 5 ++-- src/rpc/mempool.cpp | 20 ++++++++-------- src/rpc/mining.cpp | 14 ++++++------ src/rpc/rawtransaction.cpp | 6 ++--- src/rpc/txoutproof.cpp | 6 ++--- src/test/bloom_tests.cpp | 42 +++++++++++++++++----------------- src/test/fuzz/merkleblock.cpp | 2 +- src/test/merkleblock_tests.cpp | 8 +++---- src/test/pmt_tests.cpp | 22 +++++++++--------- src/wallet/rpc/backup.cpp | 4 ++-- 12 files changed, 78 insertions(+), 80 deletions(-) diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 669c6e3b700..34ff06e53a7 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -32,7 +32,7 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std: header = block.GetBlockHeader(); std::vector vMatch; - std::vector vHashes; + std::vector vHashes; vMatch.reserve(block.vtx.size()); vHashes.reserve(block.vtx.size()); @@ -55,13 +55,13 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std: } // NOLINTNEXTLINE(misc-no-recursion) -uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector &vTxid) { +uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector &vTxid) { //we can never have zero txs in a merkle block, we always need the coinbase tx //if we do not have this assert, we can hit a memory access violation when indexing into vTxid assert(vTxid.size() != 0); if (height == 0) { // hash at height 0 is the txids themselves - return vTxid[pos]; + return vTxid[pos].ToUint256(); } else { // calculate left hash uint256 left = CalcHash(height-1, pos*2, vTxid), right; @@ -76,7 +76,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve } // NOLINTNEXTLINE(misc-no-recursion) -void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector &vTxid, const std::vector &vMatch) { +void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector &vTxid, const std::vector &vMatch) { // determine whether this node is the parent of at least one matched txid bool fParentOfMatch = false; for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++) @@ -95,7 +95,7 @@ void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const st } // NOLINTNEXTLINE(misc-no-recursion) -uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch, std::vector &vnIndex) { +uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch, std::vector &vnIndex) { if (nBitsUsed >= vBits.size()) { // overflowed the bits array - failure fBad = true; @@ -111,7 +111,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns } const uint256 &hash = vHash[nHashUsed++]; if (height==0 && fParentOfMatch) { // in case of height 0, we have a matched txid - vMatch.push_back(hash); + vMatch.push_back(Txid::FromUint256(hash)); vnIndex.push_back(pos); } return hash; @@ -133,7 +133,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns } } -CPartialMerkleTree::CPartialMerkleTree(const std::vector &vTxid, const std::vector &vMatch) : nTransactions(vTxid.size()), fBad(false) { +CPartialMerkleTree::CPartialMerkleTree(const std::vector &vTxid, const std::vector &vMatch) : nTransactions(vTxid.size()), fBad(false) { // reset state vBits.clear(); vHash.clear(); @@ -149,7 +149,7 @@ CPartialMerkleTree::CPartialMerkleTree(const std::vector &vTxid, const CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {} -uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch, std::vector &vnIndex) { +uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch, std::vector &vnIndex) { vMatch.clear(); // An empty set will not work if (nTransactions == 0) diff --git a/src/merkleblock.h b/src/merkleblock.h index 945b7d3341c..8f1d45a3d77 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -73,16 +74,16 @@ protected: } /** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */ - uint256 CalcHash(int height, unsigned int pos, const std::vector &vTxid); + uint256 CalcHash(int height, unsigned int pos, const std::vector &vTxid); /** recursive function that traverses tree nodes, storing the data as bits and hashes */ - void TraverseAndBuild(int height, unsigned int pos, const std::vector &vTxid, const std::vector &vMatch); + void TraverseAndBuild(int height, unsigned int pos, const std::vector &vTxid, const std::vector &vMatch); /** * recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild. * it returns the hash of the respective node and its respective index. */ - uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch, std::vector &vnIndex); + uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector &vMatch, std::vector &vnIndex); public: @@ -97,7 +98,7 @@ public: } /** Construct a partial merkle tree from a list of transaction ids, and a mask that selects a subset of them */ - CPartialMerkleTree(const std::vector &vTxid, const std::vector &vMatch); + CPartialMerkleTree(const std::vector &vTxid, const std::vector &vMatch); CPartialMerkleTree(); @@ -106,7 +107,7 @@ public: * and their respective indices within the partial tree. * returns the merkle root, or 0 in case of failure */ - uint256 ExtractMatches(std::vector &vMatch, std::vector &vnIndex); + uint256 ExtractMatches(std::vector &vMatch, std::vector &vnIndex); /** Get number of transactions the merkle proof is indicating for cross-reference with * local blockchain knowledge. @@ -135,7 +136,7 @@ public: * Used only when a bloom filter is specified to allow * testing the transactions which matched the bloom filter. */ - std::vector > vMatchedTxn; + std::vector > vMatchedTxn; /** * Create from a CBlock, filtering transactions according to filter diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 28e6cc7bb88..ba919facaab 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2352,9 +2352,8 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& // they must either disconnect and retry or request the full block. // Thus, the protocol spec specified allows for us to provide duplicate txn here, // however we MUST always provide at least what the remote peer needs - typedef std::pair PairType; - for (PairType& pair : merkleBlock.vMatchedTxn) - MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[pair.first])); + for (const auto& [tx_idx, _] : merkleBlock.vMatchedTxn) + MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[tx_idx])); } // else // no response diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index df5d22828b3..919c30464dd 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -461,12 +461,12 @@ static RPCHelpMan getmempoolancestors() if (!request.params[1].isNull()) fVerbose = request.params[1].get_bool(); - uint256 hash = ParseHashV(request.params[0], "parameter 1"); + auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; const CTxMemPool& mempool = EnsureAnyMemPool(request.context); LOCK(mempool.cs); - const auto entry{mempool.GetEntry(Txid::FromUint256(hash))}; + const auto entry{mempool.GetEntry(txid)}; if (entry == nullptr) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); } @@ -483,10 +483,9 @@ static RPCHelpMan getmempoolancestors() UniValue o(UniValue::VOBJ); for (CTxMemPool::txiter ancestorIt : ancestors) { const CTxMemPoolEntry &e = *ancestorIt; - const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(mempool, info, e); - o.pushKV(_hash.ToString(), std::move(info)); + o.pushKV(e.GetTx().GetHash().ToString(), std::move(info)); } return o; } @@ -523,7 +522,7 @@ static RPCHelpMan getmempooldescendants() if (!request.params[1].isNull()) fVerbose = request.params[1].get_bool(); - Txid txid{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))}; + auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; const CTxMemPool& mempool = EnsureAnyMemPool(request.context); LOCK(mempool.cs); @@ -549,10 +548,9 @@ static RPCHelpMan getmempooldescendants() UniValue o(UniValue::VOBJ); for (CTxMemPool::txiter descendantIt : setDescendants) { const CTxMemPoolEntry &e = *descendantIt; - const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(mempool, info, e); - o.pushKV(_hash.ToString(), std::move(info)); + o.pushKV(e.GetTx().GetHash().ToString(), std::move(info)); } return o; } @@ -576,12 +574,12 @@ static RPCHelpMan getmempoolentry() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - uint256 hash = ParseHashV(request.params[0], "parameter 1"); + auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; const CTxMemPool& mempool = EnsureAnyMemPool(request.context); LOCK(mempool.cs); - const auto entry{mempool.GetEntry(Txid::FromUint256(hash))}; + const auto entry{mempool.GetEntry(txid)}; if (entry == nullptr) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); } @@ -1080,7 +1078,7 @@ static RPCHelpMan submitpackage() UniValue rpc_result{UniValue::VOBJ}; rpc_result.pushKV("package_msg", package_msg); UniValue tx_result_map{UniValue::VOBJ}; - std::set replaced_txids; + std::set replaced_txids; for (const auto& tx : txns) { UniValue result_inner{UniValue::VOBJ}; result_inner.pushKV("txid", tx->GetHash().GetHex()); @@ -1124,7 +1122,7 @@ static RPCHelpMan submitpackage() } rpc_result.pushKV("tx-results", std::move(tx_result_map)); UniValue replaced_list(UniValue::VARR); - for (const uint256& hash : replaced_txids) replaced_list.push_back(hash.ToString()); + for (const auto& txid : replaced_txids) replaced_list.push_back(txid.ToString()); rpc_result.pushKV("replaced-transactions", std::move(replaced_list)); return rpc_result; }, diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index f11305f16b8..c66b6c1984a 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -353,8 +353,8 @@ static RPCHelpMan generateblock() const auto& str{raw_txs_or_txids[i].get_str()}; CMutableTransaction mtx; - if (auto hash{uint256::FromHex(str)}) { - const auto tx{mempool.get(*hash)}; + if (auto txid{Txid::FromHex(str)}) { + const auto tx{mempool.get(*txid)}; if (!tx) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Transaction %s not in mempool.", str)); } @@ -517,7 +517,7 @@ static RPCHelpMan prioritisetransaction() { LOCK(cs_main); - uint256 hash(ParseHashV(request.params[0], "txid")); + auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; const auto dummy{self.MaybeArg("dummy")}; CAmount nAmount = request.params[2].getInt(); @@ -528,12 +528,12 @@ static RPCHelpMan prioritisetransaction() CTxMemPool& mempool = EnsureAnyMemPool(request.context); // Non-0 fee dust transactions are not allowed for entry, and modification not allowed afterwards - const auto& tx = mempool.get(hash); + const auto& tx = mempool.get(txid); if (mempool.m_opts.require_standard && tx && !GetDust(*tx, mempool.m_opts.dust_relay_feerate).empty()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is not supported for transactions with dust outputs."); } - mempool.PrioritiseTransaction(hash, nAmount); + mempool.PrioritiseTransaction(txid, nAmount); return true; }, }; @@ -887,14 +887,14 @@ static RPCHelpMan getblocktemplate() UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue transactions(UniValue::VARR); - std::map setTxIndex; + std::map setTxIndex; std::vector tx_fees{block_template->getTxFees()}; std::vector tx_sigops{block_template->getTxSigops()}; int i = 0; for (const auto& it : block.vtx) { const CTransaction& tx = *it; - uint256 txHash = tx.GetHash(); + Txid txHash = tx.GetHash(); setTxIndex[txHash] = i++; if (tx.IsCoinBase()) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 9c26e5c733c..c87741a5389 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -322,10 +322,10 @@ static RPCHelpMan getrawtransaction() const NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); - uint256 hash = ParseHashV(request.params[0], "parameter 1"); + auto txid{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))}; const CBlockIndex* blockindex = nullptr; - if (hash == chainman.GetParams().GenesisBlock().hashMerkleRoot) { + if (txid.ToUint256() == chainman.GetParams().GenesisBlock().hashMerkleRoot) { // Special exception for the genesis block coinbase transaction throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "The genesis block coinbase is not considered an ordinary transaction and cannot be retrieved"); } @@ -348,7 +348,7 @@ static RPCHelpMan getrawtransaction() } uint256 hash_block; - const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), hash, hash_block, chainman.m_blockman); + const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), txid, hash_block, chainman.m_blockman); if (!tx) { std::string errmsg; if (blockindex) { diff --git a/src/rpc/txoutproof.cpp b/src/rpc/txoutproof.cpp index a45e43819da..2d98053d4d6 100644 --- a/src/rpc/txoutproof.cpp +++ b/src/rpc/txoutproof.cpp @@ -150,7 +150,7 @@ static RPCHelpMan verifytxoutproof() UniValue res(UniValue::VARR); - std::vector vMatch; + std::vector vMatch; std::vector vIndex; if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) return res; @@ -165,8 +165,8 @@ static RPCHelpMan verifytxoutproof() // Check if proof is valid, only add results if so if (pindex->nTx == merkleBlock.txn.GetNumTransactions()) { - for (const uint256& hash : vMatch) { - res.push_back(hash.GetHex()); + for (const auto& txid : vMatch) { + res.push_back(txid.GetHex()); } } diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 1c732a8267e..584c970e196 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -181,12 +181,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex()); BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1U); - std::pair pair = merkleBlock.vMatchedTxn[0]; + std::pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"})); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8); - std::vector vMatched; + std::vector vMatched; std::vector vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); @@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"dd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"dd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"})); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); @@ -229,12 +229,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - std::pair pair = merkleBlock.vMatchedTxn[0]; + std::pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"})); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); - std::vector vMatched; + std::vector vMatched; std::vector vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); @@ -253,13 +253,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); - BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == Txid::FromUint256(uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"})); BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256{"6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == Txid::FromUint256(uint256{"6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"})); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2); - BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == Txid::FromUint256(uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"})); BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); @@ -286,12 +286,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - std::pair pair = merkleBlock.vMatchedTxn[0]; + std::pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"})); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); - std::vector vMatched; + std::vector vMatched; std::vector vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); @@ -310,10 +310,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); - BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == Txid::FromUint256(uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"})); BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == Txid::FromUint256(uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"})); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); @@ -341,10 +341,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"})); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); - std::vector vMatched; + std::vector vMatched; std::vector vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); @@ -376,12 +376,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - std::pair pair = merkleBlock.vMatchedTxn[0]; + std::pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"})); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6); - std::vector vMatched; + std::vector vMatched; std::vector vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); @@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"}); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"})); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3); BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); diff --git a/src/test/fuzz/merkleblock.cpp b/src/test/fuzz/merkleblock.cpp index e03e628444e..b203acb0831 100644 --- a/src/test/fuzz/merkleblock.cpp +++ b/src/test/fuzz/merkleblock.cpp @@ -43,7 +43,7 @@ FUZZ_TARGET(merkleblock) partial_merkle_tree = merkle_block.txn; }); (void)partial_merkle_tree.GetNumTransactions(); - std::vector matches; + std::vector matches; std::vector indices; (void)partial_merkle_tree.ExtractMatches(matches, indices); } diff --git a/src/test/merkleblock_tests.cpp b/src/test/merkleblock_tests.cpp index 73dbe337143..48a61a3fc0d 100644 --- a/src/test/merkleblock_tests.cpp +++ b/src/test/merkleblock_tests.cpp @@ -39,17 +39,17 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_found) // vMatchedTxn is only used when bloom filter is specified. BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U); - std::vector vMatched; + std::vector vMatched; std::vector vIndex; BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex()); BOOST_CHECK_EQUAL(vMatched.size(), 2U); // Ordered by occurrence in depth-first tree traversal. - BOOST_CHECK_EQUAL(vMatched[0].ToString(), txhash2.ToString()); + BOOST_CHECK_EQUAL(vMatched[0], txhash2); BOOST_CHECK_EQUAL(vIndex[0], 1U); - BOOST_CHECK_EQUAL(vMatched[1].ToString(), txhash1.ToString()); + BOOST_CHECK_EQUAL(vMatched[1], txhash1); BOOST_CHECK_EQUAL(vIndex[1], 8U); } @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_not_found) BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex()); BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U); - std::vector vMatched; + std::vector vMatched; std::vector vIndex; BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex()); diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 2ba48d717ab..b7bf5062649 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) // calculate actual merkle root and height uint256 merkleRoot1 = BlockMerkleRoot(block); - std::vector vTxid(nTx, uint256()); + std::vector vTxid(nTx); for (unsigned int j=0; jGetHash(); int nHeight = 1, nTx_ = nTx; @@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) for (int att = 1; att < 15; att++) { // build random subset of txid's std::vector vMatch(nTx, false); - std::vector vMatchTxid1; + std::vector vMatchTxid1; for (unsigned int j=0; j> pmt2; // extract merkle root and matched txids from copy - std::vector vMatchTxid2; + std::vector vMatchTxid2; std::vector vIndex; uint256 merkleRoot2 = pmt2.ExtractMatches(vMatchTxid2, vIndex); @@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) for (int j=0; j<4; j++) { CPartialMerkleTreeTester pmt3(pmt2); pmt3.Damage(); - std::vector vMatchTxid3; + std::vector vMatchTxid3; uint256 merkleRoot3 = pmt3.ExtractMatches(vMatchTxid3, vIndex); BOOST_CHECK(merkleRoot3 != merkleRoot1); } @@ -110,13 +110,13 @@ BOOST_AUTO_TEST_CASE(pmt_test1) BOOST_AUTO_TEST_CASE(pmt_malleability) { - std::vector vTxid{ - uint256{1}, uint256{2}, - uint256{3}, uint256{4}, - uint256{5}, uint256{6}, - uint256{7}, uint256{8}, - uint256{9}, uint256{10}, - uint256{9}, uint256{10}, + std::vector vTxid{ + Txid::FromUint256(uint256{1}), Txid::FromUint256(uint256{2}), + Txid::FromUint256(uint256{3}), Txid::FromUint256(uint256{4}), + Txid::FromUint256(uint256{5}), Txid::FromUint256(uint256{6}), + Txid::FromUint256(uint256{7}), Txid::FromUint256(uint256{8}), + Txid::FromUint256(uint256{9}), Txid::FromUint256(uint256{10}), + Txid::FromUint256(uint256{9}), Txid::FromUint256(uint256{10}), }; std::vector vMatch = {false, false, false, false, false, false, false, false, false, true, true, false}; diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp index edd1fb86c99..e8109214856 100644 --- a/src/wallet/rpc/backup.cpp +++ b/src/wallet/rpc/backup.cpp @@ -60,7 +60,7 @@ RPCHelpMan importprunedfunds() ssMB >> merkleBlock; //Search partial merkle tree in proof for our transaction and index in valid block - std::vector vMatch; + std::vector vMatch; std::vector vIndex; if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Something wrong with merkleblock"); @@ -72,7 +72,7 @@ RPCHelpMan importprunedfunds() throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); } - std::vector::const_iterator it; + std::vector::const_iterator it; if ((it = std::find(vMatch.begin(), vMatch.end(), tx.GetHash())) == vMatch.end()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof"); } From aeb0f783305c923ee7667c46ca0ff7e1b96ed45c Mon Sep 17 00:00:00 2001 From: marcofleon Date: Tue, 29 Jul 2025 15:32:57 +0100 Subject: [PATCH 3/8] refactor: Convert `mini_miner` from uint256 to Txid --- src/node/mini_miner.cpp | 13 +++++-------- src/node/mini_miner.h | 12 ++++++------ src/test/miniminer_tests.cpp | 16 ++++------------ src/txmempool.cpp | 6 +++--- src/txmempool.h | 4 ++-- 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/node/mini_miner.cpp b/src/node/mini_miner.cpp index dec1060ab7f..a1c2edcb7bb 100644 --- a/src/node/mini_miner.cpp +++ b/src/node/mini_miner.cpp @@ -16,6 +16,7 @@ #include #include +#include #include namespace node { @@ -61,12 +62,8 @@ MiniMiner::MiniMiner(const CTxMemPool& mempool, const std::vector& ou if (m_requested_outpoints_by_txid.empty()) return; // Calculate the cluster and construct the entry map. - std::vector txids_needed; - txids_needed.reserve(m_requested_outpoints_by_txid.size()); - for (const auto& [txid, _]: m_requested_outpoints_by_txid) { - txids_needed.push_back(txid); - } - const auto cluster = mempool.GatherClusters(txids_needed); + auto txids_needed{m_requested_outpoints_by_txid | std::views::keys}; + const auto cluster = mempool.GatherClusters({txids_needed.begin(), txids_needed.end()}); if (cluster.empty()) { // An empty cluster means that at least one of the transactions is missing from the mempool // (should not be possible given processing above) or DoS limit was hit. @@ -286,7 +283,7 @@ void MiniMiner::BuildMockTemplate(std::optional target_feerate) } // Track the order in which transactions were selected. for (const auto& ancestor : ancestors) { - m_inclusion_order.emplace(Txid::FromUint256(ancestor->first), sequence_num); + m_inclusion_order.emplace(ancestor->first, sequence_num); } DeleteAncestorPackage(ancestors); SanityCheck(); @@ -409,7 +406,7 @@ std::optional MiniMiner::CalculateTotalBumpFees(const CFeeRate& target_ ancestors.insert(iter); } - std::set has_been_processed; + std::set has_been_processed; while (!to_process.empty()) { auto iter = to_process.begin(); const CTransaction& tx = (*iter)->second.GetTx(); diff --git a/src/node/mini_miner.h b/src/node/mini_miner.h index 73143e829e7..d07108cb1c2 100644 --- a/src/node/mini_miner.h +++ b/src/node/mini_miner.h @@ -83,12 +83,12 @@ class MiniMiner // Set once per lifetime, fill in during initialization. // txids of to-be-replaced transactions - std::set m_to_be_replaced; + std::set m_to_be_replaced; // If multiple argument outpoints correspond to the same transaction, cache them together in // a single entry indexed by txid. Then we can just work with txids since all outpoints from // the same tx will have the same bumpfee. Excludes non-mempool transactions. - std::map> m_requested_outpoints_by_txid; + std::map> m_requested_outpoints_by_txid; // Txid to a number representing the order in which this transaction was included (smaller // number = included earlier). Transactions included in an ancestor set together have the same @@ -98,21 +98,21 @@ class MiniMiner std::map m_bump_fees; // The constructed block template - std::set m_in_block; + std::set m_in_block; // Information on the current status of the block CAmount m_total_fees{0}; int32_t m_total_vsize{0}; /** Main data structure holding the entries, can be indexed by txid */ - std::map m_entries_by_txid; + std::map m_entries_by_txid; using MockEntryMap = decltype(m_entries_by_txid); /** Vector of entries, can be sorted by ancestor feerate. */ std::vector m_entries; /** Map of txid to its descendants. Should be inclusive. */ - std::map> m_descendant_set_by_txid; + std::map> m_descendant_set_by_txid; /** Consider this ancestor package "mined" so remove all these entries from our data structures. */ void DeleteAncestorPackage(const std::set& ancestors); @@ -129,7 +129,7 @@ public: void BuildMockTemplate(std::optional target_feerate); /** Returns set of txids in the block template if one has been constructed. */ - std::set GetMockTemplateTxids() const { return m_in_block; } + std::set GetMockTemplateTxids() const { return m_in_block; } /** Constructor that takes a list of outpoints that may or may not belong to transactions in the * mempool. Copies out information about the relevant transactions in the mempool into diff --git a/src/test/miniminer_tests.cpp b/src/test/miniminer_tests.cpp index d1fec479a06..4d4cf940e37 100644 --- a/src/test/miniminer_tests.cpp +++ b/src/test/miniminer_tests.cpp @@ -103,7 +103,7 @@ BOOST_FIXTURE_TEST_CASE(miniminer_negative, TestChain100Setup) mini_miner_no_target.BuildMockTemplate(std::nullopt); const auto template_txids{mini_miner_no_target.GetMockTemplateTxids()}; BOOST_CHECK_EQUAL(template_txids.size(), 1); - BOOST_CHECK(template_txids.count(tx_mod_negative->GetHash().ToUint256()) > 0); + BOOST_CHECK(template_txids.count(tx_mod_negative->GetHash()) > 0); } BOOST_FIXTURE_TEST_CASE(miniminer_1p1c, TestChain100Setup) @@ -177,7 +177,7 @@ BOOST_FIXTURE_TEST_CASE(miniminer_1p1c, TestChain100Setup) struct TxDimensions { int32_t vsize; CAmount mod_fee; CFeeRate feerate; }; - std::map tx_dims; + std::map tx_dims; for (const auto& tx : all_transactions) { const auto& entry{*Assert(pool.GetEntry(tx->GetHash()))}; tx_dims.emplace(tx->GetHash(), TxDimensions{entry.GetTxSize(), entry.GetModifiedFee(), @@ -590,14 +590,6 @@ BOOST_FIXTURE_TEST_CASE(calculate_cluster, TestChain100Setup) CTxMemPool& pool = *Assert(m_node.mempool); LOCK2(cs_main, pool.cs); - // TODO this can be removed once the mempool interface uses Txid, Wtxid - auto convert_to_uint256_vec = [](const std::vector& vec) -> std::vector { - std::vector out; - std::transform(vec.begin(), vec.end(), std::back_inserter(out), - [](const Txid& txid) { return txid.ToUint256(); }); - return out; - }; - // Add chain of size 500 TestMemPoolEntryHelper entry; std::vector chain_txids; @@ -611,7 +603,7 @@ BOOST_FIXTURE_TEST_CASE(calculate_cluster, TestChain100Setup) const auto cluster_500tx = pool.GatherClusters({lasttx->GetHash()}); CTxMemPool::setEntries cluster_500tx_set{cluster_500tx.begin(), cluster_500tx.end()}; BOOST_CHECK_EQUAL(cluster_500tx.size(), cluster_500tx_set.size()); - const auto vec_iters_500 = pool.GetIterVec(convert_to_uint256_vec(chain_txids)); + const auto vec_iters_500 = pool.GetIterVec(chain_txids); for (const auto& iter : vec_iters_500) BOOST_CHECK(cluster_500tx_set.count(iter)); // GatherClusters stops at 500 transactions. @@ -637,7 +629,7 @@ BOOST_FIXTURE_TEST_CASE(calculate_cluster, TestChain100Setup) AddToMempool(pool, entry.Fee(CENT).FromTx(txc)); zigzag_txids.push_back(txc->GetHash()); } - const auto vec_iters_zigzag = pool.GetIterVec(convert_to_uint256_vec(zigzag_txids)); + const auto vec_iters_zigzag = pool.GetIterVec(zigzag_txids); // It doesn't matter which tx we calculate cluster for, everybody is in it. const std::vector indices{0, 22, 72, zigzag_txids.size() - 1}; for (const auto index : indices) { diff --git a/src/txmempool.cpp b/src/txmempool.cpp index bdc40cddfe1..d19d0a47270 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -983,13 +983,13 @@ CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set& hashes) cons return ret; } -std::vector CTxMemPool::GetIterVec(const std::vector& txids) const +std::vector CTxMemPool::GetIterVec(const std::vector& txids) const { AssertLockHeld(cs); std::vector ret; ret.reserve(txids.size()); for (const auto& txid : txids) { - const auto it{GetIter(Txid::FromUint256(txid))}; + const auto it{GetIter(txid)}; if (!it) return {}; ret.push_back(*it); } @@ -1227,7 +1227,7 @@ void CTxMemPool::SetLoadTried(bool load_tried) m_load_tried = load_tried; } -std::vector CTxMemPool::GatherClusters(const std::vector& txids) const +std::vector CTxMemPool::GatherClusters(const std::vector& txids) const { AssertLockHeld(cs); std::vector clustered_txs{GetIterVec(txids)}; diff --git a/src/txmempool.h b/src/txmempool.h index 03373037395..048ad23fd5f 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -491,7 +491,7 @@ public: /** Translate a list of hashes into a list of mempool iterators to avoid repeated lookups. * The nth element in txids becomes the nth element in the returned vector. If any of the txids * don't actually exist in the mempool, returns an empty vector. */ - std::vector GetIterVec(const std::vector& txids) const EXCLUSIVE_LOCKS_REQUIRED(cs); + std::vector GetIterVec(const std::vector& txids) const EXCLUSIVE_LOCKS_REQUIRED(cs); /** UpdateTransactionsFromBlock is called when adding transactions from a * disconnected block back to the mempool, new mempool entries may have @@ -548,7 +548,7 @@ public: * All txids must correspond to transaction entries in the mempool, otherwise this returns an * empty vector. This call will also exit early and return an empty vector if it collects 500 or * more transactions as a DoS protection. */ - std::vector GatherClusters(const std::vector& txids) const EXCLUSIVE_LOCKS_REQUIRED(cs); + std::vector GatherClusters(const std::vector& txids) const EXCLUSIVE_LOCKS_REQUIRED(cs); /** Calculate all in-mempool ancestors of a set of transactions not already in the mempool and * check ancestor and descendant limits. Heuristics are used to estimate the ancestor and From f6c0d1d23128f742dfdda253752cba7db9bb0679 Mon Sep 17 00:00:00 2001 From: marcofleon Date: Tue, 1 Apr 2025 14:55:26 +0100 Subject: [PATCH 4/8] mempool, refactor: Convert uint256 to Txid --- src/interfaces/chain.h | 4 +-- src/net_processing.cpp | 4 +-- src/node/interfaces.cpp | 6 ++--- src/node/mempool_persist.cpp | 8 +++--- src/node/transaction.cpp | 2 +- src/node/transaction.h | 2 +- src/rest.cpp | 2 +- src/test/blockencodings_tests.cpp | 4 +-- src/test/fuzz/package_eval.cpp | 4 +-- src/test/fuzz/rbf.cpp | 2 +- src/test/fuzz/tx_pool.cpp | 4 +-- src/test/miner_tests.cpp | 2 +- src/test/policyestimator_tests.cpp | 11 +++----- src/txmempool.cpp | 43 +++++++++++++++--------------- src/txmempool.h | 34 +++++++++++------------ src/validation.cpp | 2 +- 16 files changed, 65 insertions(+), 69 deletions(-) diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 56716ec673f..82bfdb9fd30 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -211,7 +211,7 @@ public: virtual bool isInMempool(const Txid& txid) = 0; //! Check if transaction has descendants in mempool. - virtual bool hasDescendantsInMempool(const uint256& txid) = 0; + virtual bool hasDescendantsInMempool(const Txid& txid) = 0; //! Transaction is added to memory pool, if the transaction fee is below the //! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true. @@ -222,7 +222,7 @@ public: std::string& err_string) = 0; //! Calculate mempool ancestor and descendant counts for the given transaction. - virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0; + virtual void getTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0; //! For each outpoint, calculate the fee-bumping cost to spend this outpoint at the specified // feerate, including bumping its ancestors. For example, if the target feerate is 10sat/vbyte diff --git a/src/net_processing.cpp b/src/net_processing.cpp index ba919facaab..546e14b8bce 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1577,13 +1577,13 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler& scheduler) { - std::set unbroadcast_txids = m_mempool.GetUnbroadcastTxs(); + std::set unbroadcast_txids = m_mempool.GetUnbroadcastTxs(); for (const auto& txid : unbroadcast_txids) { CTransactionRef tx = m_mempool.get(txid); if (tx != nullptr) { - RelayTransaction(Txid::FromUint256(txid), tx->GetWitnessHash()); + RelayTransaction(txid, tx->GetWitnessHash()); } else { m_mempool.RemoveUnbroadcastTx(txid, true); } diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 62172930dca..eeee4159dda 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -673,11 +673,11 @@ public: LOCK(m_node.mempool->cs); return m_node.mempool->exists(txid); } - bool hasDescendantsInMempool(const uint256& txid) override + bool hasDescendantsInMempool(const Txid& txid) override { if (!m_node.mempool) return false; LOCK(m_node.mempool->cs); - const auto entry{m_node.mempool->GetEntry(Txid::FromUint256(txid))}; + const auto entry{m_node.mempool->GetEntry(txid)}; if (entry == nullptr) return false; return entry->GetCountWithDescendants() > 1; } @@ -692,7 +692,7 @@ public: // that Chain clients do not need to know about. return TransactionError::OK == err; } - void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize, CAmount* ancestorfees) override + void getTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize, CAmount* ancestorfees) override { ancestors = descendants = 0; if (!m_node.mempool) return; diff --git a/src/node/mempool_persist.cpp b/src/node/mempool_persist.cpp index 5b0f80be6c8..19819a3af23 100644 --- a/src/node/mempool_persist.cpp +++ b/src/node/mempool_persist.cpp @@ -122,7 +122,7 @@ bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, Chainstate& active if (active_chainstate.m_chainman.m_interrupt) return false; } - std::map mapDeltas; + std::map mapDeltas; file >> mapDeltas; if (opts.apply_fee_delta_priority) { @@ -131,7 +131,7 @@ bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, Chainstate& active } } - std::set unbroadcast_txids; + std::set unbroadcast_txids; file >> unbroadcast_txids; if (opts.apply_unbroadcast_set) { unbroadcast = unbroadcast_txids.size(); @@ -154,9 +154,9 @@ bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, FopenFn mock { auto start = SteadyClock::now(); - std::map mapDeltas; + std::map mapDeltas; std::vector vinfo; - std::set unbroadcast_txids; + std::set unbroadcast_txids; static Mutex dump_mutex; LOCK(dump_mutex); diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp index 9162557bca1..7bb92872914 100644 --- a/src/node/transaction.cpp +++ b/src/node/transaction.cpp @@ -123,7 +123,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t return TransactionError::OK; } -CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, uint256& hashBlock, const BlockManager& blockman) +CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const Txid& hash, uint256& hashBlock, const BlockManager& blockman) { if (mempool && !block_index) { CTransactionRef ptx = mempool->get(hash); diff --git a/src/node/transaction.h b/src/node/transaction.h index 5f524f4e28e..2a4115817b9 100644 --- a/src/node/transaction.h +++ b/src/node/transaction.h @@ -63,7 +63,7 @@ static const CAmount DEFAULT_MAX_BURN_AMOUNT{0}; * @param[out] hashBlock The block hash, if the tx was found via -txindex or block_index * @returns The tx if found, otherwise nullptr */ -CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, uint256& hashBlock, const BlockManager& blockman); +CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const Txid& hash, uint256& hashBlock, const BlockManager& blockman); } // namespace node #endif // BITCOIN_NODE_TRANSACTION_H diff --git a/src/rest.cpp b/src/rest.cpp index e32b4c3821c..7750bdc8d82 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -817,7 +817,7 @@ static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string std::string hashStr; const RESTResponseFormat rf = ParseDataFormat(hashStr, uri_part); - auto hash{uint256::FromHex(hashStr)}; + auto hash{Txid::FromHex(hashStr)}; if (!hash) { return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); } diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index d40a0a94aef..b3d21096879 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -154,7 +154,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) AddToMempool(pool, entry.FromTx(block.vtx[2])); BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 0); - uint256 txhash; + Txid txhash; // Test with pre-forwarding tx 1, but not coinbase { @@ -225,7 +225,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) AddToMempool(pool, entry.FromTx(block.vtx[1])); BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()).use_count(), SHARED_TX_OFFSET + 0); - uint256 txhash; + Txid txhash; // Test with pre-forwarding coinbase + tx 2 with tx 1 in mempool { diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp index aa73fcdd9b5..23ea9d1f15a 100644 --- a/src/test/fuzz/package_eval.cpp +++ b/src/test/fuzz/package_eval.cpp @@ -314,7 +314,7 @@ FUZZ_TARGET(ephemeral_package_eval, .init = initialize_tx_pool) if (tx_pool.exists(txid)) { const auto tx_info{tx_pool.info(txid)}; if (GetDust(*tx_info.tx, tx_pool.m_opts.dust_relay_feerate).empty()) { - tx_pool.PrioritiseTransaction(txid.ToUint256(), delta); + tx_pool.PrioritiseTransaction(txid, delta); } } } @@ -477,7 +477,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool) txs.back()->GetHash() : PickValue(fuzzed_data_provider, mempool_outpoints).hash; const auto delta = fuzzed_data_provider.ConsumeIntegralInRange(-50 * COIN, +50 * COIN); - tx_pool.PrioritiseTransaction(txid.ToUint256(), delta); + tx_pool.PrioritiseTransaction(txid, delta); } // Remember all added transactions diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp index db8682e27c4..300f31d4408 100644 --- a/src/test/fuzz/rbf.cpp +++ b/src/test/fuzz/rbf.cpp @@ -160,7 +160,7 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) } if (fuzzed_data_provider.ConsumeBool()) { - pool.PrioritiseTransaction(mempool_txs.back().GetHash().ToUint256(), fuzzed_data_provider.ConsumeIntegralInRange(-100000, 100000)); + pool.PrioritiseTransaction(mempool_txs.back().GetHash(), fuzzed_data_provider.ConsumeIntegralInRange(-100000, 100000)); } } diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index ea65700c522..4245d3e1246 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -288,7 +288,7 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool) tx->GetHash() : PickValue(fuzzed_data_provider, outpoints_rbf).hash; const auto delta = fuzzed_data_provider.ConsumeIntegralInRange(-50 * COIN, +50 * COIN); - tx_pool.PrioritiseTransaction(txid.ToUint256(), delta); + tx_pool.PrioritiseTransaction(txid, delta); } // Remember all removed and added transactions @@ -409,7 +409,7 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool) mut_tx.GetHash() : PickValue(fuzzed_data_provider, txids); const auto delta = fuzzed_data_provider.ConsumeIntegralInRange(-50 * COIN, +50 * COIN); - tx_pool.PrioritiseTransaction(txid.ToUint256(), delta); + tx_pool.PrioritiseTransaction(txid, delta); } const auto tx = MakeTransactionRef(mut_tx); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 9207f1bfc2c..ffdf7a4de62 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -596,7 +596,7 @@ void MinerTestingSetup::TestPrioritisedMining(const CScript& scriptPubKey, const tx.vin[0].scriptSig = CScript() << OP_1; tx.vout.resize(1); tx.vout[0].nValue = 5000000000LL; // 0 fee - uint256 hashFreePrioritisedTx = tx.GetHash(); + Txid hashFreePrioritisedTx = tx.GetHash(); AddToMempool(tx_mempool, entry.Fee(0).Time(Now()).SpendsCoinbase(true).FromTx(tx)); tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 * COIN); diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index f767cd42871..bbdd815fe45 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) // added to the mempool by their associate fee // txHashes[j] is populated with transactions either of // fee = basefee * (j+1) - std::vector txHashes[10]; + std::vector txHashes[10]; // Create a transaction template CScript garbage; @@ -77,8 +77,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) /*has_no_mempool_parents=*/true)}; m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence()); } - uint256 hash = tx.GetHash(); - txHashes[j].push_back(hash); + txHashes[j].push_back(tx.GetHash()); } } //Create blocks where higher fee txs are included more often @@ -178,8 +177,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) /*has_no_mempool_parents=*/true)}; m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence()); } - uint256 hash = tx.GetHash(); - txHashes[j].push_back(hash); + txHashes[j].push_back(tx.GetHash()); } } { @@ -242,8 +240,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) /*has_no_mempool_parents=*/true)}; m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence()); } - uint256 hash = tx.GetHash(); - CTransactionRef ptx = mpool.get(hash); + CTransactionRef ptx = mpool.get(tx.GetHash()); if (ptx) block.push_back(ptx); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d19d0a47270..6bb910e30e6 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -55,7 +55,7 @@ bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp) } void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants, - const std::set& setExclude, std::set& descendants_to_remove) + const std::set& setExclude, std::set& descendants_to_remove) { CTxMemPoolEntry::Children stageEntries, descendants; stageEntries = updateIt->GetMemPoolChildrenConst(); @@ -105,7 +105,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendan mapTx.modify(updateIt, [=](CTxMemPoolEntry& e) { e.UpdateDescendantState(modifySize, modifyFee, modifyCount); }); } -void CTxMemPool::UpdateTransactionsFromBlock(const std::vector& vHashesToUpdate) +void CTxMemPool::UpdateTransactionsFromBlock(const std::vector& vHashesToUpdate) { AssertLockHeld(cs); // For each entry in vHashesToUpdate, store the set of in-mempool, but not @@ -115,29 +115,29 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector& vHashes // Use a set for lookups into vHashesToUpdate (these entries are already // accounted for in the state of their ancestors) - std::set setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); + std::set setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); - std::set descendants_to_remove; + std::set descendants_to_remove; // Iterate in reverse, so that whenever we are looking at a transaction // we are sure that all in-mempool descendants have already been processed. // This maximizes the benefit of the descendant cache and guarantees that // CTxMemPoolEntry::m_children will be updated, an assumption made in // UpdateForDescendants. - for (const uint256& hash : vHashesToUpdate | std::views::reverse) { + for (const Txid& hash : vHashesToUpdate | std::views::reverse) { // calculate children from mapNextTx txiter it = mapTx.find(hash); if (it == mapTx.end()) { continue; } - auto iter = mapNextTx.lower_bound(COutPoint(Txid::FromUint256(hash), 0)); + auto iter = mapNextTx.lower_bound(COutPoint(hash, 0)); // First calculate the children, and update CTxMemPoolEntry::m_children to // include them, and update their CTxMemPoolEntry::m_parents to include this tx. // we cache the in-mempool children to avoid duplicate updates { WITH_FRESH_EPOCH(m_epoch); for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) { - const uint256 &childHash = iter->second->GetHash(); + const Txid &childHash = iter->second->GetHash(); txiter childIter = mapTx.find(childHash); assert(childIter != mapTx.end()); // We can skip updating entries we've encountered before or that @@ -154,7 +154,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector& vHashes for (const auto& txid : descendants_to_remove) { // This txid may have been removed already in a prior call to removeRecursive. // Therefore we ensure it is not yet removed already. - if (const std::optional txiter = GetIter(Txid::FromUint256(txid))) { + if (const std::optional txiter = GetIter(txid)) { removeRecursive((*txiter)->GetTx(), MemPoolRemovalReason::SIZELIMIT); } } @@ -780,12 +780,11 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei for (const auto& input: tx.vin) mempoolDuplicate.SpendCoin(input.prevout); AddCoins(mempoolDuplicate, tx, std::numeric_limits::max()); } - for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) { - uint256 hash = it->second->GetHash(); - indexed_transaction_set::const_iterator it2 = mapTx.find(hash); - const CTransaction& tx = it2->GetTx(); - assert(it2 != mapTx.end()); - assert(&tx == it->second); + for (const auto& [_, next_tx] : mapNextTx) { + auto it = mapTx.find(next_tx->GetHash()); + const CTransaction& tx = it->GetTx(); + assert(it != mapTx.end()); + assert(&tx == next_tx); } assert(totalTxSize == checkTotal); @@ -876,7 +875,7 @@ const CTxMemPoolEntry* CTxMemPool::GetEntry(const Txid& txid) const return i == mapTx.end() ? nullptr : &(*i); } -CTransactionRef CTxMemPool::get(const uint256& hash) const +CTransactionRef CTxMemPool::get(const Txid& hash) const { LOCK(cs); indexed_transaction_set::const_iterator i = mapTx.find(hash); @@ -885,7 +884,7 @@ CTransactionRef CTxMemPool::get(const uint256& hash) const return i->GetSharedTx(); } -void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta) +void CTxMemPool::PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta) { { LOCK(cs); @@ -921,17 +920,17 @@ void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeD } } -void CTxMemPool::ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const +void CTxMemPool::ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const { AssertLockHeld(cs); - std::map::const_iterator pos = mapDeltas.find(hash); + std::map::const_iterator pos = mapDeltas.find(hash); if (pos == mapDeltas.end()) return; const CAmount &delta = pos->second; nFeeDelta += delta; } -void CTxMemPool::ClearPrioritisation(const uint256& hash) +void CTxMemPool::ClearPrioritisation(const Txid& hash) { AssertLockHeld(cs); mapDeltas.erase(hash); @@ -962,7 +961,7 @@ const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const std::optional CTxMemPool::GetIter(const Txid& txid) const { AssertLockHeld(cs); - auto it = mapTx.find(txid.ToUint256()); + auto it = mapTx.find(txid); return it != mapTx.end() ? std::make_optional(it) : std::nullopt; } @@ -1048,7 +1047,7 @@ size_t CTxMemPool::DynamicMemoryUsage() const { return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(txns_randomized) + cachedInnerUsage; } -void CTxMemPool::RemoveUnbroadcastTx(const uint256& txid, const bool unchecked) { +void CTxMemPool::RemoveUnbroadcastTx(const Txid& txid, const bool unchecked) { LOCK(cs); if (m_unbroadcast_txids.erase(txid)) @@ -1203,7 +1202,7 @@ uint64_t CTxMemPool::CalculateDescendantMaximum(txiter entry) const { return maximum; } -void CTxMemPool::GetTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* const ancestorsize, CAmount* const ancestorfees) const { +void CTxMemPool::GetTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& descendants, size_t* const ancestorsize, CAmount* const ancestorfees) const { LOCK(cs); auto it = mapTx.find(txid); ancestors = descendants = 0; diff --git a/src/txmempool.h b/src/txmempool.h index 048ad23fd5f..8b55d9cd521 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -57,7 +57,7 @@ bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp) EXCLUSIVE // extracts a transaction hash from CTxMemPoolEntry or CTransactionRef struct mempoolentry_txid { - typedef uint256 result_type; + typedef Txid result_type; result_type operator() (const CTxMemPoolEntry &entry) const { return entry.GetTx().GetHash(); @@ -72,7 +72,7 @@ struct mempoolentry_txid // extracts a transaction witness-hash from CTxMemPoolEntry or CTransactionRef struct mempoolentry_wtxid { - typedef uint256 result_type; + typedef Wtxid result_type; result_type operator() (const CTxMemPoolEntry &entry) const { return entry.GetTx().GetWitnessHash(); @@ -387,7 +387,7 @@ private: /** * Track locally submitted transactions to periodically retry initial broadcast. */ - std::set m_unbroadcast_txids GUARDED_BY(cs); + std::set m_unbroadcast_txids GUARDED_BY(cs); /** @@ -414,7 +414,7 @@ private: public: indirectmap mapNextTx GUARDED_BY(cs); - std::map mapDeltas GUARDED_BY(cs); + std::map mapDeltas GUARDED_BY(cs); using Options = kernel::MemPoolOptions; @@ -459,9 +459,9 @@ public: bool HasNoInputsOf(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs); /** Affect CreateNewBlock prioritisation of transactions */ - void PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta); - void ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs); - void ClearPrioritisation(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs); + void PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta); + void ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs); + void ClearPrioritisation(const Txid& hash) EXCLUSIVE_LOCKS_REQUIRED(cs); struct delta_info { /** Whether this transaction is in the mempool. */ @@ -471,7 +471,7 @@ public: /** The modified fee (base fee + delta) of this entry. Only present if in_mempool=true. */ std::optional modified_fee; /** The prioritised transaction's txid. */ - const uint256 txid; + const Txid txid; }; /** Return a vector of all entries in mapDeltas with their corresponding delta_info. */ std::vector GetPrioritisedTransactions() const EXCLUSIVE_LOCKS_REQUIRED(!cs); @@ -506,7 +506,7 @@ public: * @param[in] vHashesToUpdate The set of txids from the * disconnected block that have been accepted back into the mempool. */ - void UpdateTransactionsFromBlock(const std::vector& vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main) LOCKS_EXCLUDED(m_epoch); + void UpdateTransactionsFromBlock(const std::vector& vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main) LOCKS_EXCLUDED(m_epoch); /** * Try to calculate all in-mempool ancestors of entry. @@ -595,7 +595,7 @@ public: * When ancestors is non-zero (ie, the transaction itself is in the mempool), * ancestorsize and ancestorfees will also be set to the appropriate values. */ - void GetTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) const; + void GetTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) const; /** * @returns true if an initial attempt to load the persisted mempool was made, regardless of @@ -641,7 +641,7 @@ public: const CTxMemPoolEntry* GetEntry(const Txid& txid) const LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(cs); - CTransactionRef get(const uint256& hash) const; + CTransactionRef get(const Txid& hash) const; template TxMempoolInfo info(const T& id) const @@ -666,26 +666,26 @@ public: size_t DynamicMemoryUsage() const; /** Adds a transaction to the unbroadcast set */ - void AddUnbroadcastTx(const uint256& txid) + void AddUnbroadcastTx(const Txid& txid) { LOCK(cs); // Sanity check the transaction is in the mempool & insert into // unbroadcast set. - if (exists(Txid::FromUint256(txid))) m_unbroadcast_txids.insert(txid); + if (exists(txid)) m_unbroadcast_txids.insert(txid); }; /** Removes a transaction from the unbroadcast set */ - void RemoveUnbroadcastTx(const uint256& txid, const bool unchecked = false); + void RemoveUnbroadcastTx(const Txid& txid, const bool unchecked = false); /** Returns transactions in unbroadcast set */ - std::set GetUnbroadcastTxs() const + std::set GetUnbroadcastTxs() const { LOCK(cs); return m_unbroadcast_txids; } /** Returns whether a txid is in the unbroadcast set */ - bool IsUnbroadcastTx(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs) + bool IsUnbroadcastTx(const Txid& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs) { AssertLockHeld(cs); return m_unbroadcast_txids.count(txid) != 0; @@ -744,7 +744,7 @@ private: * removeRecursive them. */ void UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants, - const std::set& setExclude, std::set& descendants_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs); + const std::set& setExclude, std::set& descendants_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs); /** Update ancestors of hash to add/remove it as a descendant transaction. */ void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs); /** Set ancestor state for an entry */ diff --git a/src/validation.cpp b/src/validation.cpp index 90e70834bcb..69cc84bba22 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -303,7 +303,7 @@ void Chainstate::MaybeUpdateMempoolForReorg( AssertLockHeld(cs_main); AssertLockHeld(m_mempool->cs); - std::vector vHashUpdate; + std::vector vHashUpdate; { // disconnectpool is ordered so that the front is the most recently-confirmed // transaction (the last tx of the block at the tip) in the disconnected chain. From d2ecd6815d89c9b089b55bc96fdf93b023be8dda Mon Sep 17 00:00:00 2001 From: marcofleon Date: Tue, 1 Apr 2025 15:26:25 +0100 Subject: [PATCH 5/8] policy, refactor: Convert uint256 to Txid --- src/policy/fees.cpp | 6 +++--- src/policy/fees.h | 6 +++--- src/policy/packages.cpp | 10 +++++----- src/policy/rbf.cpp | 11 +++++------ src/policy/rbf.h | 6 +++--- src/test/fuzz/policy_estimator.cpp | 2 +- src/test/rbf_tests.cpp | 2 +- src/validation.cpp | 2 +- 8 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index e385f548d30..a650a1326b0 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -519,16 +519,16 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe } } -bool CBlockPolicyEstimator::removeTx(uint256 hash) +bool CBlockPolicyEstimator::removeTx(Txid hash) { LOCK(m_cs_fee_estimator); return _removeTx(hash, /*inBlock=*/false); } -bool CBlockPolicyEstimator::_removeTx(const uint256& hash, bool inBlock) +bool CBlockPolicyEstimator::_removeTx(const Txid& hash, bool inBlock) { AssertLockHeld(m_cs_fee_estimator); - std::map::iterator pos = mapMemPoolTxs.find(hash); + std::map::iterator pos = mapMemPoolTxs.find(hash); if (pos != mapMemPoolTxs.end()) { feeStats->removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex, inBlock); shortStats->removeTx(pos->second.blockHeight, nBestSeenHeight, pos->second.bucketIndex, inBlock); diff --git a/src/policy/fees.h b/src/policy/fees.h index a95cc19dd45..b355b65a346 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -212,7 +212,7 @@ public: EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator); /** Remove a transaction from the mempool tracking stats for non BLOCK removal reasons*/ - bool removeTx(uint256 hash) + bool removeTx(Txid hash) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator); /** DEPRECATED. Return a feerate estimate */ @@ -287,7 +287,7 @@ private: }; // map of txids to information about that transaction - std::map mapMemPoolTxs GUARDED_BY(m_cs_fee_estimator); + std::map mapMemPoolTxs GUARDED_BY(m_cs_fee_estimator); /** Classes to track historical data on transaction confirmations */ std::unique_ptr feeStats PT_GUARDED_BY(m_cs_fee_estimator); @@ -315,7 +315,7 @@ private: unsigned int MaxUsableEstimate() const EXCLUSIVE_LOCKS_REQUIRED(m_cs_fee_estimator); /** A non-thread-safe helper for the removeTx function */ - bool _removeTx(const uint256& hash, bool inBlock) + bool _removeTx(const Txid& hash, bool inBlock) EXCLUSIVE_LOCKS_REQUIRED(m_cs_fee_estimator); }; diff --git a/src/policy/packages.cpp b/src/policy/packages.cpp index 693adcdfd0b..187bd467579 100644 --- a/src/policy/packages.cpp +++ b/src/policy/packages.cpp @@ -16,7 +16,7 @@ /** IsTopoSortedPackage where a set of txids has been pre-populated. The set is assumed to be correct and * is mutated within this function (even if return value is false). */ -bool IsTopoSortedPackage(const Package& txns, std::unordered_set& later_txids) +bool IsTopoSortedPackage(const Package& txns, std::unordered_set& later_txids) { // Avoid misusing this function: later_txids should contain the txids of txns. Assume(txns.size() == later_txids.size()); @@ -42,7 +42,7 @@ bool IsTopoSortedPackage(const Package& txns, std::unordered_set later_txids; + std::unordered_set later_txids; std::transform(txns.cbegin(), txns.cend(), std::inserter(later_txids, later_txids.end()), [](const auto& tx) { return tx->GetHash(); }); @@ -91,7 +91,7 @@ bool IsWellFormedPackage(const Package& txns, PackageValidationState& state, boo return state.Invalid(PackageValidationResult::PCKG_POLICY, "package-too-large"); } - std::unordered_set later_txids; + std::unordered_set later_txids; std::transform(txns.cbegin(), txns.cend(), std::inserter(later_txids, later_txids.end()), [](const auto& tx) { return tx->GetHash(); }); @@ -123,7 +123,7 @@ bool IsChildWithParents(const Package& package) // The package is expected to be sorted, so the last transaction is the child. const auto& child = package.back(); - std::unordered_set input_txids; + std::unordered_set input_txids; std::transform(child->vin.cbegin(), child->vin.cend(), std::inserter(input_txids, input_txids.end()), [](const auto& input) { return input.prevout.hash; }); @@ -136,7 +136,7 @@ bool IsChildWithParents(const Package& package) bool IsChildWithParentsTree(const Package& package) { if (!IsChildWithParents(package)) return false; - std::unordered_set parent_txids; + std::unordered_set parent_txids; std::transform(package.cbegin(), package.cend() - 1, std::inserter(parent_txids, parent_txids.end()), [](const auto& ptx) { return ptx->GetHash(); }); // Each parent must not have an input who is one of the other parents. diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp index dc74f43b354..210b94915cc 100644 --- a/src/policy/rbf.cpp +++ b/src/policy/rbf.cpp @@ -62,7 +62,6 @@ std::optional GetEntriesForConflicts(const CTransaction& tx, CTxMemPool::setEntries& all_conflicts) { AssertLockHeld(pool.cs); - const uint256 txid = tx.GetHash(); uint64_t nConflictingCount = 0; for (const auto& mi : iters_conflicting) { nConflictingCount += mi->GetCountWithDescendants(); @@ -72,7 +71,7 @@ std::optional GetEntriesForConflicts(const CTransaction& tx, // times), but we just want to be conservative to avoid doing too much work. if (nConflictingCount > MAX_REPLACEMENT_CANDIDATES) { return strprintf("rejecting replacement %s; too many potential replacements (%d > %d)", - txid.ToString(), + tx.GetHash().ToString(), nConflictingCount, MAX_REPLACEMENT_CANDIDATES); } @@ -89,7 +88,7 @@ std::optional HasNoNewUnconfirmed(const CTransaction& tx, const CTxMemPool::setEntries& iters_conflicting) { AssertLockHeld(pool.cs); - std::set parents_of_conflicts; + std::set parents_of_conflicts; for (const auto& mi : iters_conflicting) { for (const CTxIn& txin : mi->GetTx().vin) { parents_of_conflicts.insert(txin.prevout.hash); @@ -118,7 +117,7 @@ std::optional HasNoNewUnconfirmed(const CTransaction& tx, std::optional EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& ancestors, const std::set& direct_conflicts, - const uint256& txid) + const Txid& txid) { for (CTxMemPool::txiter ancestorIt : ancestors) { const Txid& hashAncestor = ancestorIt->GetTx().GetHash(); @@ -133,7 +132,7 @@ std::optional EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& std::optional PaysMoreThanConflicts(const CTxMemPool::setEntries& iters_conflicting, CFeeRate replacement_feerate, - const uint256& txid) + const Txid& txid) { for (const auto& mi : iters_conflicting) { // Don't allow the replacement to reduce the feerate of the mempool. @@ -161,7 +160,7 @@ std::optional PaysForRBF(CAmount original_fees, CAmount replacement_fees, size_t replacement_vsize, CFeeRate relay_fee, - const uint256& txid) + const Txid& txid) { // Rule #3: The replacement fees must be greater than or equal to fees of the // transactions it replaces, otherwise the bandwidth used by those conflicting transactions diff --git a/src/policy/rbf.h b/src/policy/rbf.h index 3cc0fc3149f..cc397b463dc 100644 --- a/src/policy/rbf.h +++ b/src/policy/rbf.h @@ -90,7 +90,7 @@ std::optional HasNoNewUnconfirmed(const CTransaction& tx, const CTx */ std::optional EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& ancestors, const std::set& direct_conflicts, - const uint256& txid); + const Txid& txid); /** Check that the feerate of the replacement transaction(s) is higher than the feerate of each * of the transactions in iters_conflicting. @@ -98,7 +98,7 @@ std::optional EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& * @returns error message if fees insufficient, otherwise std::nullopt. */ std::optional PaysMoreThanConflicts(const CTxMemPool::setEntries& iters_conflicting, - CFeeRate replacement_feerate, const uint256& txid); + CFeeRate replacement_feerate, const Txid& txid); /** The replacement transaction must pay more fees than the original transactions. The additional * fees must pay for the replacement's bandwidth at or above the incremental relay feerate. @@ -113,7 +113,7 @@ std::optional PaysForRBF(CAmount original_fees, CAmount replacement_fees, size_t replacement_vsize, CFeeRate relay_fee, - const uint256& txid); + const Txid& txid); /** * The replacement transaction must improve the feerate diagram of the mempool. diff --git a/src/test/fuzz/policy_estimator.cpp b/src/test/fuzz/policy_estimator.cpp index 37e37964182..8455a23284d 100644 --- a/src/test/fuzz/policy_estimator.cpp +++ b/src/test/fuzz/policy_estimator.cpp @@ -85,7 +85,7 @@ FUZZ_TARGET(policy_estimator, .init = initialize_policy_estimator) block_policy_estimator.processBlock(txs, current_height); }, [&] { - (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider)); + (void)block_policy_estimator.removeTx(Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider))); }, [&] { block_policy_estimator.FlushUnconfirmed(); diff --git a/src/test/rbf_tests.cpp b/src/test/rbf_tests.cpp index 0052276eac4..cbbea61a53c 100644 --- a/src/test/rbf_tests.cpp +++ b/src/test/rbf_tests.cpp @@ -196,7 +196,7 @@ BOOST_FIXTURE_TEST_CASE(rbf_helper_functions, TestChain100Setup) entry5_low, entry6_low_prioritised, entry7_high, entry8_high}; CTxMemPool::setEntries empty_set; - const auto unused_txid{GetRandHash()}; + const auto unused_txid = Txid::FromUint256(GetRandHash()); // Tests for PaysMoreThanConflicts // These tests use feerate, not absolute fee. diff --git a/src/validation.cpp b/src/validation.cpp index 69cc84bba22..0d68475aa6c 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1088,7 +1088,7 @@ bool MemPoolAccept::ReplacementChecks(Workspace& ws) AssertLockHeld(m_pool.cs); const CTransaction& tx = *ws.m_ptx; - const uint256& hash = ws.m_hash; + const Txid& hash = ws.m_hash; TxValidationState& state = ws.m_state; CFeeRate newFeeRate(ws.m_modified_fees, ws.m_vsize); From 9c24cda72edb2085edfa75296d6b42fab34433d9 Mon Sep 17 00:00:00 2001 From: marcofleon Date: Thu, 31 Jul 2025 17:05:00 +0100 Subject: [PATCH 6/8] refactor: Convert remaining instances from uint256 to Txid These remaining miscellaneous changes were identified by commenting out the `operator const uint256&` conversion and the `Compare(const uint256&)` method from `transaction_identifier.h`. --- src/blockencodings.cpp | 2 +- src/consensus/merkle.cpp | 6 ++--- src/headerssync.cpp | 2 +- src/headerssync.h | 2 +- src/index/txindex.cpp | 19 +++++++------- src/index/txindex.h | 2 +- src/kernel/coinstats.cpp | 6 ++--- src/kernel/disconnected_transactions.h | 2 +- src/net_processing.cpp | 17 ++++++------ src/node/txdownloadman_impl.cpp | 28 ++++++++++---------- src/signet.cpp | 4 +-- src/test/disconnected_transactions.cpp | 2 +- src/test/fuzz/merkle.cpp | 4 +-- src/test/fuzz/p2p_headers_presync.cpp | 2 +- src/test/merkle_tests.cpp | 8 +++--- src/test/util/setup_common.cpp | 8 ++++++ src/test/util/setup_common.h | 2 ++ src/test/validation_tests.cpp | 8 +++--- src/txmempool.h | 2 +- src/util/hasher.cpp | 8 ++++++ src/util/hasher.h | 36 +++++++++++++++++++++++--- src/validation.cpp | 4 +-- src/wallet/spend.cpp | 2 +- src/wallet/wallet.cpp | 2 +- src/zmq/zmqpublishnotifier.cpp | 8 +++--- 25 files changed, 117 insertions(+), 69 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 947f605d8e6..3f61a122e67 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -42,7 +42,7 @@ void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const { uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const Wtxid& wtxid) const { static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids calculation assumes 6-byte shorttxids"); - return SipHashUint256(shorttxidk0, shorttxidk1, wtxid) & 0xffffffffffffL; + return SipHashUint256(shorttxidk0, shorttxidk1, wtxid.ToUint256()) & 0xffffffffffffL; } ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector& extra_txn) { diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index 7dd24e1868f..e274ed821a5 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -68,7 +68,7 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) std::vector leaves; leaves.resize(block.vtx.size()); for (size_t s = 0; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetHash(); + leaves[s] = block.vtx[s]->GetHash().ToUint256(); } return ComputeMerkleRoot(std::move(leaves), mutated); } @@ -79,7 +79,7 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated) leaves.resize(block.vtx.size()); leaves[0].SetNull(); // The witness hash of the coinbase is 0. for (size_t s = 1; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetWitnessHash(); + leaves[s] = block.vtx[s]->GetWitnessHash().ToUint256(); } return ComputeMerkleRoot(std::move(leaves), mutated); } @@ -185,7 +185,7 @@ std::vector TransactionMerklePath(const CBlock& block, uint32_t positio std::vector leaves; leaves.resize(block.vtx.size()); for (size_t s = 0; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetHash(); + leaves[s] = block.vtx[s]->GetHash().ToUint256(); } return ComputeMerklePath(leaves, position); } diff --git a/src/headerssync.cpp b/src/headerssync.cpp index 9e8b1905168..fbe2026ecae 100644 --- a/src/headerssync.cpp +++ b/src/headerssync.cpp @@ -48,7 +48,7 @@ HeadersSyncState::HeadersSyncState(NodeId id, const Consensus::Params& consensus /** Free any memory in use, and mark this object as no longer usable. This is * required to guarantee that we won't reuse this object with the same - * SaltedTxidHasher for another sync. */ + * SaltedUint256Hasher for another sync. */ void HeadersSyncState::Finalize() { Assume(m_download_state != State::FINAL); diff --git a/src/headerssync.h b/src/headerssync.h index 2e7017f115d..56380c66fe2 100644 --- a/src/headerssync.h +++ b/src/headerssync.h @@ -224,7 +224,7 @@ private: arith_uint256 m_current_chain_work; /** m_hasher is a salted hasher for making our 1-bit commitments to headers we've seen. */ - const SaltedTxidHasher m_hasher; + const SaltedUint256Hasher m_hasher; /** A queue of commitment bits, created during the 1st phase, and verified during the 2nd. */ bitdeque<> m_header_commitments; diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp index 4bb6dc74447..2a7c0066b08 100644 --- a/src/index/txindex.cpp +++ b/src/index/txindex.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include constexpr uint8_t DB_TXINDEX{'t'}; @@ -24,26 +25,26 @@ public: /// Read the disk location of the transaction data with the given hash. Returns false if the /// transaction hash is not indexed. - bool ReadTxPos(const uint256& txid, CDiskTxPos& pos) const; + bool ReadTxPos(const Txid& txid, CDiskTxPos& pos) const; /// Write a batch of transaction positions to the DB. - [[nodiscard]] bool WriteTxs(const std::vector>& v_pos); + [[nodiscard]] bool WriteTxs(const std::vector>& v_pos); }; TxIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) : BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "txindex", n_cache_size, f_memory, f_wipe) {} -bool TxIndex::DB::ReadTxPos(const uint256 &txid, CDiskTxPos& pos) const +bool TxIndex::DB::ReadTxPos(const Txid& txid, CDiskTxPos& pos) const { - return Read(std::make_pair(DB_TXINDEX, txid), pos); + return Read(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos); } -bool TxIndex::DB::WriteTxs(const std::vector>& v_pos) +bool TxIndex::DB::WriteTxs(const std::vector>& v_pos) { CDBBatch batch(*this); - for (const auto& tuple : v_pos) { - batch.Write(std::make_pair(DB_TXINDEX, tuple.first), tuple.second); + for (const auto& [txid, pos] : v_pos) { + batch.Write(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos); } return WriteBatch(batch); } @@ -61,7 +62,7 @@ bool TxIndex::CustomAppend(const interfaces::BlockInfo& block) assert(block.data); CDiskTxPos pos({block.file_number, block.data_pos}, GetSizeOfCompactSize(block.data->vtx.size())); - std::vector> vPos; + std::vector> vPos; vPos.reserve(block.data->vtx.size()); for (const auto& tx : block.data->vtx) { vPos.emplace_back(tx->GetHash(), pos); @@ -72,7 +73,7 @@ bool TxIndex::CustomAppend(const interfaces::BlockInfo& block) BaseIndex::DB& TxIndex::GetDB() const { return *m_db; } -bool TxIndex::FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRef& tx) const +bool TxIndex::FindTx(const Txid& tx_hash, uint256& block_hash, CTransactionRef& tx) const { CDiskTxPos postx; if (!m_db->ReadTxPos(tx_hash, postx)) { diff --git a/src/index/txindex.h b/src/index/txindex.h index ef835fe5d7d..f8236c92844 100644 --- a/src/index/txindex.h +++ b/src/index/txindex.h @@ -42,7 +42,7 @@ public: /// @param[out] block_hash The hash of the block the transaction is found in. /// @param[out] tx The transaction itself. /// @return true if transaction is found, false otherwise - bool FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRef& tx) const; + bool FindTx(const Txid& tx_hash, uint256& block_hash, CTransactionRef& tx) const; }; /// The global transaction index, used in GetTransaction. May be null. diff --git a/src/kernel/coinstats.cpp b/src/kernel/coinstats.cpp index 81c496ab342..6270f365f4e 100644 --- a/src/kernel/coinstats.cpp +++ b/src/kernel/coinstats.cpp @@ -98,7 +98,7 @@ static void ApplyHash(T& hash_obj, const Txid& hash, const std::map& outputs) +static void ApplyStats(CCoinsStats& stats, const std::map& outputs) { assert(!outputs.empty()); stats.nTransactions++; @@ -126,7 +126,7 @@ static bool ComputeUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, c Coin coin; if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { if (!outputs.empty() && key.hash != prevkey) { - ApplyStats(stats, prevkey, outputs); + ApplyStats(stats, outputs); ApplyHash(hash_obj, prevkey, outputs); outputs.clear(); } @@ -140,7 +140,7 @@ static bool ComputeUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, c pcursor->Next(); } if (!outputs.empty()) { - ApplyStats(stats, prevkey, outputs); + ApplyStats(stats, outputs); ApplyHash(hash_obj, prevkey, outputs); } diff --git a/src/kernel/disconnected_transactions.h b/src/kernel/disconnected_transactions.h index 401ec435e6b..bc098f71aaf 100644 --- a/src/kernel/disconnected_transactions.h +++ b/src/kernel/disconnected_transactions.h @@ -41,7 +41,7 @@ private: const size_t m_max_mem_usage; std::list queuedTx; using TxList = decltype(queuedTx); - std::unordered_map iters_by_txid; + std::unordered_map iters_by_txid; /** Trim the earliest-added entries until we are within memory bounds. */ std::vector LimitMemoryUsage(); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 546e14b8bce..810627a14e7 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3030,7 +3030,7 @@ std::optional PeerManagerImpl::ProcessInvalidTx(NodeId AddToCompactExtraTransactions(ptx); } for (const Txid& parent_txid : unique_parents) { - if (peer) AddKnownTx(*peer, parent_txid); + if (peer) AddKnownTx(*peer, parent_txid.ToUint256()); } MaybePunishNodeForTx(nodeid, state); @@ -4280,12 +4280,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, CTransactionRef ptx; vRecv >> TX_WITH_WITNESS(ptx); - const CTransaction& tx = *ptx; - const uint256& txid = ptx->GetHash(); - const uint256& wtxid = ptx->GetWitnessHash(); + const Txid& txid = ptx->GetHash(); + const Wtxid& wtxid = ptx->GetWitnessHash(); - const uint256& hash = peer->m_wtxid_relay ? wtxid : txid; + const uint256& hash = peer->m_wtxid_relay ? wtxid.ToUint256() : txid.ToUint256(); AddKnownTx(*peer, hash); LOCK2(cs_main, m_tx_download_mutex); @@ -4296,13 +4295,13 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, // Always relay transactions received from peers with forcerelay // permission, even if they were already in the mempool, allowing // the node to function as a gateway for nodes hidden behind it. - if (!m_mempool.exists(tx.GetHash())) { + if (!m_mempool.exists(txid)) { LogPrintf("Not relaying non-mempool transaction %s (wtxid=%s) from forcerelay peer=%d\n", - tx.GetHash().ToString(), tx.GetWitnessHash().ToString(), pfrom.GetId()); + txid.ToString(), wtxid.ToString(), pfrom.GetId()); } else { LogPrintf("Force relaying tx %s (wtxid=%s) from peer=%d\n", - tx.GetHash().ToString(), tx.GetWitnessHash().ToString(), pfrom.GetId()); - RelayTransaction(tx.GetHash(), tx.GetWitnessHash()); + txid.ToString(), wtxid.ToString(), pfrom.GetId()); + RelayTransaction(txid, wtxid); } } diff --git a/src/node/txdownloadman_impl.cpp b/src/node/txdownloadman_impl.cpp index 0105fe3d609..91bc7f3bcbd 100644 --- a/src/node/txdownloadman_impl.cpp +++ b/src/node/txdownloadman_impl.cpp @@ -104,8 +104,8 @@ void TxDownloadManagerImpl::BlockConnected(const std::shared_ptr& if (ptx->HasWitness()) { RecentConfirmedTransactionsFilter().insert(ptx->GetWitnessHash().ToUint256()); } - m_txrequest.ForgetTxHash(ptx->GetHash()); - m_txrequest.ForgetTxHash(ptx->GetWitnessHash()); + m_txrequest.ForgetTxHash(ptx->GetHash().ToUint256()); + m_txrequest.ForgetTxHash(ptx->GetWitnessHash().ToUint256()); } } @@ -324,8 +324,8 @@ void TxDownloadManagerImpl::MempoolAcceptedTx(const CTransactionRef& tx) { // As this version of the transaction was acceptable, we can forget about any requests for it. // No-op if the tx is not in txrequest. - m_txrequest.ForgetTxHash(tx->GetHash()); - m_txrequest.ForgetTxHash(tx->GetWitnessHash()); + m_txrequest.ForgetTxHash(tx->GetHash().ToUint256()); + m_txrequest.ForgetTxHash(tx->GetWitnessHash().ToUint256()); m_orphanage->AddChildrenToWorkSet(*tx, m_opts.m_rng); // If it came from the orphanage, remove it. No-op if the tx is not in txorphanage. @@ -406,8 +406,8 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction // // Search by txid and, if the tx has a witness, wtxid std::vector orphan_resolution_candidates{nodeid}; - m_txrequest.GetCandidatePeers(ptx->GetHash(), orphan_resolution_candidates); - if (ptx->HasWitness()) m_txrequest.GetCandidatePeers(ptx->GetWitnessHash(), orphan_resolution_candidates); + m_txrequest.GetCandidatePeers(ptx->GetHash().ToUint256(), orphan_resolution_candidates); + if (ptx->HasWitness()) m_txrequest.GetCandidatePeers(ptx->GetWitnessHash().ToUint256(), orphan_resolution_candidates); for (const auto& nodeid : orphan_resolution_candidates) { if (MaybeAddOrphanResolutionCandidate(unique_parents, ptx->GetWitnessHash(), nodeid, now)) { @@ -416,8 +416,8 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction } // Once added to the orphan pool, a tx is considered AlreadyHave, and we shouldn't request it anymore. - m_txrequest.ForgetTxHash(tx.GetHash()); - m_txrequest.ForgetTxHash(tx.GetWitnessHash()); + m_txrequest.ForgetTxHash(tx.GetHash().ToUint256()); + m_txrequest.ForgetTxHash(tx.GetWitnessHash().ToUint256()); } else { unique_parents.clear(); LogDebug(BCLog::MEMPOOL, "not keeping orphan with rejected parents %s (wtxid=%s)\n", @@ -431,8 +431,8 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction // from any of our non-wtxidrelay peers. RecentRejectsFilter().insert(tx.GetHash().ToUint256()); RecentRejectsFilter().insert(tx.GetWitnessHash().ToUint256()); - m_txrequest.ForgetTxHash(tx.GetHash()); - m_txrequest.ForgetTxHash(tx.GetWitnessHash()); + m_txrequest.ForgetTxHash(tx.GetHash().ToUint256()); + m_txrequest.ForgetTxHash(tx.GetWitnessHash().ToUint256()); } } } else if (state.GetResult() == TxValidationResult::TX_WITNESS_STRIPPED) { @@ -467,7 +467,7 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction } else { RecentRejectsFilter().insert(ptx->GetWitnessHash().ToUint256()); } - m_txrequest.ForgetTxHash(ptx->GetWitnessHash()); + m_txrequest.ForgetTxHash(ptx->GetWitnessHash().ToUint256()); // If the transaction failed for TX_INPUTS_NOT_STANDARD, // then we know that the witness was irrelevant to the policy // failure, since this check depends only on the txid @@ -480,7 +480,7 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction // rolling bloom filter. if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && ptx->HasWitness()) { RecentRejectsFilter().insert(ptx->GetHash().ToUint256()); - m_txrequest.ForgetTxHash(ptx->GetHash()); + m_txrequest.ForgetTxHash(ptx->GetHash().ToUint256()); } } @@ -508,8 +508,8 @@ std::pair> TxDownloadManagerImpl::Receive const Wtxid& wtxid = ptx->GetWitnessHash(); // Mark that we have received a response - m_txrequest.ReceivedResponse(nodeid, txid); - if (ptx->HasWitness()) m_txrequest.ReceivedResponse(nodeid, wtxid); + m_txrequest.ReceivedResponse(nodeid, txid.ToUint256()); + if (ptx->HasWitness()) m_txrequest.ReceivedResponse(nodeid, wtxid.ToUint256()); // First check if we should drop this tx. // We do the AlreadyHaveTx() check using wtxid, rather than txid - in the diff --git a/src/signet.cpp b/src/signet.cpp index 45d279d2bf0..742d03d9178 100644 --- a/src/signet.cpp +++ b/src/signet.cpp @@ -59,9 +59,9 @@ static uint256 ComputeModifiedMerkleRoot(const CMutableTransaction& cb, const CB { std::vector leaves; leaves.resize(block.vtx.size()); - leaves[0] = cb.GetHash(); + leaves[0] = cb.GetHash().ToUint256(); for (size_t s = 1; s < block.vtx.size(); ++s) { - leaves[s] = block.vtx[s]->GetHash(); + leaves[s] = block.vtx[s]->GetHash().ToUint256(); } return ComputeMerkleRoot(std::move(leaves)); } diff --git a/src/test/disconnected_transactions.cpp b/src/test/disconnected_transactions.cpp index d4dc124b7b1..7897e5f15c0 100644 --- a/src/test/disconnected_transactions.cpp +++ b/src/test/disconnected_transactions.cpp @@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(disconnectpool_memory_limits) // is within an expected range. // Overhead for the hashmap depends on number of buckets - std::unordered_map temp_map; + std::unordered_map temp_map; temp_map.reserve(1); const size_t MAP_1{memusage::DynamicUsage(temp_map)}; temp_map.reserve(100); diff --git a/src/test/fuzz/merkle.cpp b/src/test/fuzz/merkle.cpp index 84055ac861c..4bb91faf0b8 100644 --- a/src/test/fuzz/merkle.cpp +++ b/src/test/fuzz/merkle.cpp @@ -19,7 +19,7 @@ uint256 ComputeMerkleRootFromPath(const CBlock& block, uint32_t position, const throw std::out_of_range("Position out of range"); } - uint256 current_hash = block.vtx[position]->GetHash(); + uint256 current_hash = block.vtx[position]->GetHash().ToUint256(); for (const uint256& sibling : merkle_path) { if (position % 2 == 0) { @@ -47,7 +47,7 @@ FUZZ_TARGET(merkle) tx_hashes.reserve(num_txs); for (size_t i = 0; i < num_txs; ++i) { - tx_hashes.push_back(block->vtx[i]->GetHash()); + tx_hashes.push_back(block->vtx[i]->GetHash().ToUint256()); } // Test ComputeMerkleRoot diff --git a/src/test/fuzz/p2p_headers_presync.cpp b/src/test/fuzz/p2p_headers_presync.cpp index a2c3a0f3e62..9aebac30557 100644 --- a/src/test/fuzz/p2p_headers_presync.cpp +++ b/src/test/fuzz/p2p_headers_presync.cpp @@ -139,7 +139,7 @@ CBlock ConsumeBlock(FuzzedDataProvider& fuzzed_data_provider, const uint256& pre tx.vout[0].nValue = 0; tx.vin[0].scriptSig.resize(2); block.vtx.push_back(MakeTransactionRef(tx)); - block.hashMerkleRoot = block.vtx[0]->GetHash(); + block.hashMerkleRoot = block.vtx[0]->GetHash().ToUint256(); return block; } diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index f8cb0094fc7..cad23321ce9 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -29,7 +29,7 @@ static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::ve vMerkleTree.clear(); vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. for (std::vector::const_iterator it(block.vtx.begin()); it != block.vtx.end(); ++it) - vMerkleTree.push_back((*it)->GetHash()); + vMerkleTree.push_back((*it)->GetHash().ToUint256()); int j = 0; bool mutated = false; for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) @@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(merkle_test) std::vector newBranch = TransactionMerklePath(block, mtx); std::vector oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx); BOOST_CHECK(oldBranch == newBranch); - BOOST_CHECK(ComputeMerkleRootFromBranch(block.vtx[mtx]->GetHash(), newBranch, mtx) == oldRoot); + BOOST_CHECK(ComputeMerkleRootFromBranch(block.vtx[mtx]->GetHash().ToUint256(), newBranch, mtx) == oldRoot); } } } @@ -166,7 +166,7 @@ BOOST_AUTO_TEST_CASE(merkle_test_oneTx_block) mtx.nLockTime = 0; block.vtx[0] = MakeTransactionRef(std::move(mtx)); uint256 root = BlockMerkleRoot(block, &mutated); - BOOST_CHECK_EQUAL(root, block.vtx[0]->GetHash()); + BOOST_CHECK_EQUAL(root, block.vtx[0]->GetHash().ToUint256()); BOOST_CHECK_EQUAL(mutated, false); } @@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(merkle_test_BlockWitness) std::vector hashes; hashes.resize(block.vtx.size()); hashes[0].SetNull(); - hashes[1] = block.vtx[1]->GetHash(); + hashes[1] = block.vtx[1]->GetHash().ToUint256(); uint256 merkleRootofHashes = ComputeMerkleRoot(hashes); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 76a42d19ea2..0fc7991e570 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -629,3 +629,11 @@ std::ostream& operator<<(std::ostream& os, const uint256& num) { return os << num.ToString(); } + +std::ostream& operator<<(std::ostream& os, const Txid& txid) { + return os << txid.ToString(); +} + +std::ostream& operator<<(std::ostream& os, const Wtxid& wtxid) { + return os << wtxid.ToString(); +} diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index 57bea9086b9..150f50650ba 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -291,6 +291,8 @@ inline std::ostream& operator<<(std::ostream& os, const std::optional& v) std::ostream& operator<<(std::ostream& os, const arith_uint256& num); std::ostream& operator<<(std::ostream& os, const uint160& num); std::ostream& operator<<(std::ostream& os, const uint256& num); +std::ostream& operator<<(std::ostream& os, const Txid& txid); +std::ostream& operator<<(std::ostream& os, const Wtxid& wtxid); // @} /** diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp index 7e86b3a35c1..5d4c3ee1f1d 100644 --- a/src/test/validation_tests.cpp +++ b/src/test/validation_tests.cpp @@ -214,9 +214,9 @@ BOOST_AUTO_TEST_CASE(block_malleation) // Block with a single coinbase tx is mutated if the merkle root is not // equal to the coinbase tx's hash. block.vtx.push_back(create_coinbase_tx()); - BOOST_CHECK(block.vtx[0]->GetHash() != block.hashMerkleRoot); + BOOST_CHECK(block.vtx[0]->GetHash().ToUint256() != block.hashMerkleRoot); BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false)); - block.hashMerkleRoot = block.vtx[0]->GetHash(); + block.hashMerkleRoot = block.vtx[0]->GetHash().ToUint256(); BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false)); // Block with two transactions is mutated if the merkle root does not @@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE(block_malleation) mtx.vout.resize(1); mtx.vout[0].scriptPubKey.resize(4); block.vtx.push_back(MakeTransactionRef(mtx)); - block.hashMerkleRoot = block.vtx.back()->GetHash(); + block.hashMerkleRoot = block.vtx.back()->GetHash().ToUint256(); assert(block.vtx.back()->IsCoinBase()); assert(GetSerializeSize(TX_NO_WITNESS(block.vtx.back())) == 64); } @@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(block_malleation) HashWriter hasher; hasher.write(tx1.GetHash()); hasher.write(tx2.GetHash()); - assert(hasher.GetHash() == tx3.GetHash()); + assert(hasher.GetHash() == tx3.GetHash().ToUint256()); // Verify that tx3 is 64 bytes in size (without witness). assert(GetSerializeSize(TX_NO_WITNESS(tx3)) == 64); } diff --git a/src/txmempool.h b/src/txmempool.h index 8b55d9cd521..5c81876a361 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -313,7 +313,7 @@ public: boost::multi_index::hashed_unique< boost::multi_index::tag, mempoolentry_wtxid, - SaltedTxidHasher + SaltedWtxidHasher >, // sorted by fee rate boost::multi_index::ordered_non_unique< diff --git a/src/util/hasher.cpp b/src/util/hasher.cpp index 117cfe8dcd1..c4051ae0013 100644 --- a/src/util/hasher.cpp +++ b/src/util/hasher.cpp @@ -7,10 +7,18 @@ #include #include +SaltedUint256Hasher::SaltedUint256Hasher() : + k0{FastRandomContext().rand64()}, + k1{FastRandomContext().rand64()} {} + SaltedTxidHasher::SaltedTxidHasher() : k0{FastRandomContext().rand64()}, k1{FastRandomContext().rand64()} {} +SaltedWtxidHasher::SaltedWtxidHasher() : + k0{FastRandomContext().rand64()}, + k1{FastRandomContext().rand64()} {} + SaltedOutpointHasher::SaltedOutpointHasher(bool deterministic) : k0{deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64()}, k1{deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} diff --git a/src/util/hasher.h b/src/util/hasher.h index 3a75c91a3ef..be5d9eb13df 100644 --- a/src/util/hasher.h +++ b/src/util/hasher.h @@ -11,9 +11,24 @@ #include #include +#include #include #include +class SaltedUint256Hasher +{ +private: + /** Salt */ + const uint64_t k0, k1; + +public: + SaltedUint256Hasher(); + + size_t operator()(const uint256& hash) const { + return SipHashUint256(k0, k1, hash); + } +}; + class SaltedTxidHasher { private: @@ -23,11 +38,26 @@ private: public: SaltedTxidHasher(); - size_t operator()(const uint256& txid) const { - return SipHashUint256(k0, k1, txid); + size_t operator()(const Txid& txid) const { + return SipHashUint256(k0, k1, txid.ToUint256()); } }; +class SaltedWtxidHasher +{ +private: + /** Salt */ + const uint64_t k0, k1; + +public: + SaltedWtxidHasher(); + + size_t operator()(const Wtxid& wtxid) const { + return SipHashUint256(k0, k1, wtxid.ToUint256()); + } +}; + + class SaltedOutpointHasher { private: @@ -47,7 +77,7 @@ public: * @see https://gcc.gnu.org/onlinedocs/gcc-13.2.0/libstdc++/manual/manual/unordered_associative.html */ size_t operator()(const COutPoint& id) const noexcept { - return SipHashUint256Extra(k0, k1, id.hash, id.n); + return SipHashUint256Extra(k0, k1, id.hash.ToUint256(), id.n); } }; diff --git a/src/validation.cpp b/src/validation.cpp index 0d68475aa6c..91adbdff11f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1275,7 +1275,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws) AssertLockHeld(cs_main); AssertLockHeld(m_pool.cs); const CTransaction& tx = *ws.m_ptx; - const uint256& hash = ws.m_hash; + const Txid& hash = ws.m_hash; TxValidationState& state = ws.m_state; // Check again against the current block tip's script verification @@ -1322,7 +1322,7 @@ void MemPoolAccept::FinalizeSubpackage(const ATMPArgs& args) const bool replaced_with_tx{m_subpackage.m_changeset->GetTxCount() == 1}; if (replaced_with_tx) { const CTransaction& tx = m_subpackage.m_changeset->GetAddedTxn(0); - tx_or_package_hash = tx.GetHash(); + tx_or_package_hash = tx.GetHash().ToUint256(); log_string += strprintf("New tx %s (wtxid=%s, fees=%s, vsize=%s)", tx.GetHash().ToString(), tx.GetWitnessHash().ToString(), diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index 250377afcfa..4ae34d0bb4c 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -327,7 +327,7 @@ CoinsResult AvailableCoins(const CWallet& wallet, std::set trusted_parents; // Cache for whether each tx passes the tx level checks (first bool), and whether the transaction is "safe" (second bool) - std::unordered_map, SaltedTxidHasher> tx_safe_cache; + std::unordered_map, SaltedTxidHasher> tx_safe_cache; for (const auto& [outpoint, txo] : wallet.GetTXOs()) { const CWalletTx& wtx = txo.GetWalletTx(); const CTxOut& output = txo.GetTxOut(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 91a494c379f..5e7bec48c0b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2319,7 +2319,7 @@ util::Result CWallet::RemoveTxs(WalletBatch& batch, std::vector& txs for (const auto& txin : it->second.tx->vin) mapTxSpends.erase(txin.prevout); for (unsigned int i = 0; i < it->second.tx->vout.size(); ++i) { - m_txos.erase(COutPoint(Txid::FromUint256(hash), i)); + m_txos.erase(COutPoint(hash, i)); } mapWallet.erase(it); NotifyTransactionChanged(hash, CT_DELETED); diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 1e7aa11ce9b..693d70c8437 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -230,7 +230,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { - uint256 hash = transaction.GetHash(); + uint256 hash = transaction.GetHash().ToUint256(); LogDebug(BCLog::ZMQ, "Publish hashtx %s to %s\n", hash.GetHex(), this->address); uint8_t data[32]; for (unsigned int i = 0; i < 32; i++) { @@ -254,7 +254,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { - uint256 hash = transaction.GetHash(); + uint256 hash = transaction.GetHash().ToUint256(); LogDebug(BCLog::ZMQ, "Publish rawtx %s to %s\n", hash.GetHex(), this->address); DataStream ss; ss << TX_WITH_WITNESS(transaction); @@ -290,14 +290,14 @@ bool CZMQPublishSequenceNotifier::NotifyBlockDisconnect(const CBlockIndex *pinde bool CZMQPublishSequenceNotifier::NotifyTransactionAcceptance(const CTransaction &transaction, uint64_t mempool_sequence) { - uint256 hash = transaction.GetHash(); + uint256 hash = transaction.GetHash().ToUint256(); LogDebug(BCLog::ZMQ, "Publish hashtx mempool acceptance %s to %s\n", hash.GetHex(), this->address); return SendSequenceMsg(*this, hash, /* Mempool (A)cceptance */ 'A', mempool_sequence); } bool CZMQPublishSequenceNotifier::NotifyTransactionRemoval(const CTransaction &transaction, uint64_t mempool_sequence) { - uint256 hash = transaction.GetHash(); + uint256 hash = transaction.GetHash().ToUint256(); LogDebug(BCLog::ZMQ, "Publish hashtx mempool removal %s to %s\n", hash.GetHex(), this->address); return SendSequenceMsg(*this, hash, /* Mempool (R)emoval */ 'R', mempool_sequence); } From 6f068f65de17951dc459bc8637e5de15b84ca445 Mon Sep 17 00:00:00 2001 From: marcofleon Date: Thu, 31 Jul 2025 17:45:22 +0100 Subject: [PATCH 7/8] Remove implicit uint256 conversion and comparison --- src/util/transaction_identifier.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/util/transaction_identifier.h b/src/util/transaction_identifier.h index 30302f061f2..b59f2e77c3d 100644 --- a/src/util/transaction_identifier.h +++ b/src/util/transaction_identifier.h @@ -24,9 +24,6 @@ class transaction_identifier // Note: Use FromUint256 externally instead. transaction_identifier(const uint256& wrapped) : m_wrapped{wrapped} {} - // TODO: Comparisons with uint256 should be disallowed once we have - // converted most of the code to using the new txid types. - constexpr int Compare(const uint256& other) const { return m_wrapped.Compare(other); } constexpr int Compare(const transaction_identifier& other) const { return m_wrapped.Compare(other.m_wrapped); } template constexpr int Compare(const Other& other) const @@ -65,15 +62,6 @@ public: constexpr const std::byte* end() const { return reinterpret_cast(m_wrapped.end()); } template void Serialize(Stream& s) const { m_wrapped.Serialize(s); } template void Unserialize(Stream& s) { m_wrapped.Unserialize(s); } - - /** Conversion function to `uint256`. - * - * Note: new code should use `ToUint256`. - * - * TODO: This should be removed once the majority of the code has switched - * to using the Txid and Wtxid types. Until then it makes for a smoother - * transition to allow this conversion. */ - operator const uint256&() const LIFETIMEBOUND { return m_wrapped; } }; /** Txid commits to all transaction fields except the witness. */ From de0675f9de5feae1f070840ad7218b1378fb880b Mon Sep 17 00:00:00 2001 From: marcofleon Date: Fri, 1 Aug 2025 13:29:27 +0100 Subject: [PATCH 8/8] refactor: Move `transaction_identifier.h` to primitives Moves the file from `src/util` to `src/primitives`. Now that the refactor is complete, Txid and Wtxid are fundamental types, so it makes sense for them to reside in `src/primitives`. --- src/index/txindex.cpp | 2 +- src/interfaces/wallet.h | 2 +- src/merkleblock.h | 2 +- src/primitives/transaction.cpp | 2 +- src/primitives/transaction.h | 2 +- src/{util => primitives}/transaction_identifier.h | 6 +++--- src/qt/sendcoinsdialog.h | 2 +- src/qt/transactionrecord.h | 2 +- src/qt/transactionview.h | 2 +- src/qt/walletmodel.h | 2 +- src/test/fuzz/hex.cpp | 2 +- src/test/transaction_tests.cpp | 2 +- src/test/uint256_tests.cpp | 2 +- src/txmempool.h | 2 +- src/wallet/receive.h | 2 +- src/wallet/rpc/transactions.cpp | 2 +- src/wallet/spend.cpp | 2 +- src/wallet/wallet.h | 2 +- src/wallet/walletdb.cpp | 2 +- src/wallet/walletdb.h | 2 +- 20 files changed, 22 insertions(+), 22 deletions(-) rename src/{util => primitives}/transaction_identifier.h (95%) diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp index 2a7c0066b08..11dd856e1b6 100644 --- a/src/index/txindex.cpp +++ b/src/index/txindex.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include constexpr uint8_t DB_TXINDEX{'t'}; diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 94869aff5af..412cbb613e3 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -9,12 +9,12 @@ #include #include #include +#include #include #include