refactor: Convert uint256 to Txid #33116

pull marcofleon wants to merge 8 commits into bitcoin:master from marcofleon:2025/07/txid-type-safety changing 75 files +323 −305
  1. marcofleon commented at 1:45 pm on August 1, 2025: contributor

    This is the final leg of the type safety refactor.

    All of these changes are straightforward uint256 –> Txid along with any necessary explicit conversions. Also, transaction_identifier.h is moved to primitives in the last commit, as Txid and Wtxid become fundamental types after this PR.

  2. DrahtBot added the label Refactoring on Aug 1, 2025
  3. DrahtBot commented at 1:45 pm on August 1, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33116.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK stickies-v, janb84, dergoegge, theStack
    Stale ACK maflcko, kevkevinpal

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33094 (refactor: unify container presence checks by l0rinc)
    • #33066 (p2p: never check tx rejections by txid by glozow)
    • #33042 (refactor: inline constant return values from dbwrapper write methods by l0rinc)
    • #32998 (Bump SCRIPT_VERIFY flags to 64 bit by ajtowns)
    • #32966 (Silent Payments: Receiving by Eunovo)
    • #32844 (RPC/txoutproof: Support including (and verifying) proofs of wtxid by luke-jr)
    • #32497 (merkle: pre‑reserve leaves to prevent reallocs with odd vtx count by l0rinc)
    • #31308 (ci, iwyu: Treat warnings as errors for specific directories by hebasto)
    • #30442 ([IBD] precalculate SipHash constant salt calculations by l0rinc)
    • #30079 (Fee Estimation: Ignore all transactions that are CPFP’d by ismaelsadeeq)
    • #29641 (scripted-diff: Use LogInfo over LogPrintf [WIP, NOMERGE, DRAFT] by maflcko)
    • #28201 (Silent Payments: sending by josibake)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  4. marcofleon force-pushed on Aug 1, 2025
  5. DrahtBot added the label CI failed on Aug 1, 2025
  6. DrahtBot commented at 1:51 pm on August 1, 2025: contributor

    🚧 At least one of the CI tasks failed. Task lint: https://github.com/bitcoin/bitcoin/runs/47204972085 LLM reason (✨ experimental): The CI failure is caused by a missing include guard in the file src/primitives/transaction_identifier.h, detected during a lint check.

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  7. marcofleon force-pushed on Aug 1, 2025
  8. DrahtBot removed the label CI failed on Aug 1, 2025
  9. in src/rpc/mempool.cpp:464 in 92c5e147d9 outdated
    460@@ -461,12 +461,12 @@ static RPCHelpMan getmempoolancestors()
    461     if (!request.params[1].isNull())
    462         fVerbose = request.params[1].get_bool();
    463 
    464-    uint256 hash = ParseHashV(request.params[0], "parameter 1");
    465+    auto hash{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))};
    


    janb84 commented at 5:39 pm on August 4, 2025:

    NIT; is the variable name still descriptive ? would something like txId not be better suited ?

    0    auto txid{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))};
    

    marcofleon commented at 1:03 pm on August 5, 2025:
    fixed
  10. DrahtBot added the label Needs rebase on Aug 4, 2025
  11. in src/rest.cpp:820 in 92c5e147d9 outdated
    816@@ -817,7 +817,7 @@ static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string
    817     std::string hashStr;
    818     const RESTResponseFormat rf = ParseDataFormat(hashStr, uri_part);
    819 
    820-    auto hash{uint256::FromHex(hashStr)};
    821+    auto hash{Txid::FromHex(hashStr)};
    


    janb84 commented at 6:10 pm on August 4, 2025:

    NIT; is the variable name still descriptive ? would something like txId not be better suited ?

    0    auto txid{Txid::FromHex(hashStr)};
    

    marcofleon commented at 1:04 pm on August 5, 2025:
    Left this one as is because hash seems to be used quite a bit throughout the gui and I don’t want to change more code than I do currently.
  12. in src/rpc/mempool.cpp:1127 in 92c5e147d9 outdated
    1123@@ -1124,7 +1124,7 @@ static RPCHelpMan submitpackage()
    1124             }
    1125             rpc_result.pushKV("tx-results", std::move(tx_result_map));
    1126             UniValue replaced_list(UniValue::VARR);
    1127-            for (const uint256& hash : replaced_txids) replaced_list.push_back(hash.ToString());
    1128+            for (const Txid& hash : replaced_txids) replaced_list.push_back(hash.ToString());
    


    janb84 commented at 6:12 pm on August 4, 2025:

    NIT; is the variable name still descriptive ?

    0            for (const Txid& txid : replaced_txids) replaced_list.push_back(txid.ToString());
    

    marcofleon commented at 1:05 pm on August 5, 2025:
    fixed, along with the other ones in the rpc code
  13. janb84 commented at 6:13 pm on August 4, 2025: contributor

    Concept ACK 92c5e147d9445e126f86a08538200d1f6a390efd

    This PR is the last pr of the Txid type safety refactor initiative. In this PR transaction_identifier.h is moved to primitives to finish the refactor and uint256 to Txid (where relevant) along with any necessary explicit conversions. Which seems all correct.

    During my code review, I have found some optional NITS regarding the use of variable name “hash”. Is this still a descriptive name after this refactor?

    Steps undertaken:

    • Code review ✅
    • Build & tested. ✅
  14. Clean up `FindTxForGetData`
    Adds back a comment that was unintentionally deleted in
    the GenTxid refactor.
    49b3d3a92a
  15. marcofleon force-pushed on Aug 5, 2025
  16. marcofleon commented at 1:05 pm on August 5, 2025: contributor
    Addressed @janb84’s comments and rebased after #32941.
  17. DrahtBot removed the label Needs rebase on Aug 5, 2025
  18. janb84 commented at 5:22 pm on August 5, 2025: contributor

    re ACK a20724d926d5844168c6a13fa8293df8c8927efe

    changes since last ACK:

    • Rebase
    • Changes related to my Nit (Thanks for incorporating my suggestions!)
  19. dergoegge approved
  20. dergoegge commented at 9:25 am on August 8, 2025: member
    Code review ACK a20724d926d5844168c6a13fa8293df8c8927efe
  21. fanquake requested review from stickies-v on Aug 8, 2025
  22. in src/net_processing.cpp:2355 in a20724d926 outdated
    2351@@ -2352,7 +2352,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
    2352                 // they must either disconnect and retry or request the full block.
    2353                 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
    2354                 // however we MUST always provide at least what the remote peer needs
    2355-                typedef std::pair<unsigned int, uint256> PairType;
    2356+                typedef std::pair<unsigned int, Txid> PairType;
    


    stickies-v commented at 10:37 am on August 8, 2025:

    nit: we don’t actually use the Txid element here, so we can avoid the typedef altogether:

     0diff --git a/src/net_processing.cpp b/src/net_processing.cpp
     1index 318b50f7fe..30074bff71 100644
     2--- a/src/net_processing.cpp
     3+++ b/src/net_processing.cpp
     4@@ -2352,9 +2352,8 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
     5                 // they must either disconnect and retry or request the full block.
     6                 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
     7                 // however we MUST always provide at least what the remote peer needs
     8-                typedef std::pair<unsigned int, Txid> PairType;
     9-                for (PairType& pair : merkleBlock.vMatchedTxn)
    10-                    MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[pair.first]));
    11+                for (auto& [tx_idx, _] : merkleBlock.vMatchedTxn)
    12+                    MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[tx_idx]));
    13             }
    14             // else
    15             // no response
    
  23. in src/rpc/mempool.cpp:464 in a20724d926 outdated
    460@@ -461,12 +461,12 @@ static RPCHelpMan getmempoolancestors()
    461     if (!request.params[1].isNull())
    462         fVerbose = request.params[1].get_bool();
    463 
    464-    uint256 hash = ParseHashV(request.params[0], "parameter 1");
    465+    auto txid{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))};
    


    stickies-v commented at 10:49 am on August 8, 2025:
    orthogonal nit: not sure why we’re passing “parameter 1” instead of “txid” (here, + in 2 more locations), less clear and suffers from 0-indexing ambiguity.
  24. in src/rpc/mempool.cpp:489 in a20724d926 outdated
    482@@ -483,10 +483,10 @@ static RPCHelpMan getmempoolancestors()
    483         UniValue o(UniValue::VOBJ);
    484         for (CTxMemPool::txiter ancestorIt : ancestors) {
    485             const CTxMemPoolEntry &e = *ancestorIt;
    486-            const uint256& _hash = e.GetTx().GetHash();
    487+            const Txid& hash = e.GetTx().GetHash();
    488             UniValue info(UniValue::VOBJ);
    489             entryToJSON(mempool, info, e);
    490-            o.pushKV(_hash.ToString(), std::move(info));
    491+            o.pushKV(hash.ToString(), std::move(info));
    


    stickies-v commented at 10:52 am on August 8, 2025:

    nit: inlining it is more clear imo (+below)

     0diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
     1index 18363ddebc..a37e4cf4b8 100644
     2--- a/src/rpc/mempool.cpp
     3+++ b/src/rpc/mempool.cpp
     4@@ -483,10 +483,9 @@ static RPCHelpMan getmempoolancestors()
     5         UniValue o(UniValue::VOBJ);
     6         for (CTxMemPool::txiter ancestorIt : ancestors) {
     7             const CTxMemPoolEntry &e = *ancestorIt;
     8-            const Txid& hash = e.GetTx().GetHash();
     9             UniValue info(UniValue::VOBJ);
    10             entryToJSON(mempool, info, e);
    11-            o.pushKV(hash.ToString(), std::move(info));
    12+            o.pushKV(e.GetTx().GetHash().ToString(), std::move(info));
    13         }
    14         return o;
    15     }
    16@@ -549,10 +548,9 @@ static RPCHelpMan getmempooldescendants()
    17         UniValue o(UniValue::VOBJ);
    18         for (CTxMemPool::txiter descendantIt : setDescendants) {
    19             const CTxMemPoolEntry &e = *descendantIt;
    20-            const Txid& hash = e.GetTx().GetHash();
    21             UniValue info(UniValue::VOBJ);
    22             entryToJSON(mempool, info, e);
    23-            o.pushKV(hash.ToString(), std::move(info));
    24+            o.pushKV(e.GetTx().GetHash().ToString(), std::move(info));
    25         }
    26         return o;
    27     }
    
  25. in src/test/merkleblock_tests.cpp:42 in a20724d926 outdated
    38@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_found)
    39     // vMatchedTxn is only used when bloom filter is specified.
    40     BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U);
    41 
    42-    std::vector<uint256> vMatched;
    43+    std::vector<Txid> vMatched;
    


    stickies-v commented at 11:15 am on August 8, 2025:

    nit: now that both types are identical, we can do direct comparison:

     0diff --git a/src/test/merkleblock_tests.cpp b/src/test/merkleblock_tests.cpp
     1index 243214d329..48a61a3fc0 100644
     2--- a/src/test/merkleblock_tests.cpp
     3+++ b/src/test/merkleblock_tests.cpp
     4@@ -46,10 +46,10 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_found)
     5     BOOST_CHECK_EQUAL(vMatched.size(), 2U);
     6 
     7     // Ordered by occurrence in depth-first tree traversal.
     8-    BOOST_CHECK_EQUAL(vMatched[0].ToString(), txhash2.ToString());
     9+    BOOST_CHECK_EQUAL(vMatched[0], txhash2);
    10     BOOST_CHECK_EQUAL(vIndex[0], 1U);
    11 
    12-    BOOST_CHECK_EQUAL(vMatched[1].ToString(), txhash1.ToString());
    13+    BOOST_CHECK_EQUAL(vMatched[1], txhash1);
    14     BOOST_CHECK_EQUAL(vIndex[1], 8U);
    15 }
    16 
    
  26. in src/node/mini_miner.cpp:64 in a20724d926 outdated
    60@@ -61,7 +61,7 @@ MiniMiner::MiniMiner(const CTxMemPool& mempool, const std::vector<COutPoint>& ou
    61     if (m_requested_outpoints_by_txid.empty()) return;
    62 
    63     // Calculate the cluster and construct the entry map.
    64-    std::vector<uint256> txids_needed;
    65+    std::vector<Txid> txids_needed;
    


    stickies-v commented at 11:33 am on August 8, 2025:

    nit: could modernize

     0diff --git a/src/node/mini_miner.cpp b/src/node/mini_miner.cpp
     1index c26355d832..a1c2edcb7b 100644
     2--- a/src/node/mini_miner.cpp
     3+++ b/src/node/mini_miner.cpp
     4@@ -16,6 +16,7 @@
     5 
     6 #include <algorithm>
     7 #include <numeric>
     8+#include <ranges>
     9 #include <utility>
    10 
    11 namespace node {
    12@@ -61,12 +62,8 @@ MiniMiner::MiniMiner(const CTxMemPool& mempool, const std::vector<COutPoint>& ou
    13     if (m_requested_outpoints_by_txid.empty()) return;
    14 
    15     // Calculate the cluster and construct the entry map.
    16-    std::vector<Txid> txids_needed;
    17-    txids_needed.reserve(m_requested_outpoints_by_txid.size());
    18-    for (const auto& [txid, _]: m_requested_outpoints_by_txid) {
    19-        txids_needed.push_back(txid);
    20-    }
    21-    const auto cluster = mempool.GatherClusters(txids_needed);
    22+    auto txids_needed{m_requested_outpoints_by_txid | std::views::keys};
    23+    const auto cluster = mempool.GatherClusters({txids_needed.begin(), txids_needed.end()});
    24     if (cluster.empty()) {
    25         // An empty cluster means that at least one of the transactions is missing from the mempool
    26         // (should not be possible given processing above) or DoS limit was hit.
    
  27. maflcko commented at 11:37 am on August 8, 2025: member

    review ACK a20724d926d5844168c6a13fa8293df8c8927efe 🎰

    Signature:

    0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    2trusted comment: review ACK a20724d926d5844168c6a13fa8293df8c8927efe 🎰
    3owjWK+M1xuldjVXGuTv8u/HzGJbx30wzLvhYH1vVwALP65R1cq9YqC+QVHEwpFHaQTLY9RmEbhRByKiC25jNBQ==
    
  28. in src/util/hasher.h:41 in 5528e0f6e0 outdated
    37@@ -23,8 +38,9 @@ class SaltedTxidHasher
    38 public:
    39     SaltedTxidHasher();
    40 
    41-    size_t operator()(const uint256& txid) const {
    42-        return SipHashUint256(k0, k1, txid);
    43+    template <TxidOrWtxid T>
    


    maflcko commented at 11:40 am on August 8, 2025:
    nit in 5528e0f6e01438f15ed997269bdb4db55873c0ba: Seems a bit odd why this is required. Shouldn’t call sites only either put txid or wtxid in here, known at compile time? Also, it seems a bit confusing to call it txid-hasher, when it hashes the wtxid.

    marcofleon commented at 4:13 pm on August 8, 2025:
    You’re saying have both a txid and a wtxid hasher, yes? I think that would make sense.
  29. in src/headerssync.h:227 in a20724d926 outdated
    223@@ -224,7 +224,7 @@ class HeadersSyncState {
    224     arith_uint256 m_current_chain_work;
    225 
    226     /** m_hasher is a salted hasher for making our 1-bit commitments to headers we've seen. */
    227-    const SaltedTxidHasher m_hasher;
    228+    const SaltedUint256Hasher m_hasher;
    


    maflcko commented at 11:46 am on August 8, 2025:
    doc-nit: you’ll also have to adjust the cpp file
  30. in src/test/bloom_tests.cpp:186 in a20724d926 outdated
    180@@ -181,12 +181,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
    181     BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex());
    182 
    183     BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1U);
    184-    std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
    185+    std::pair<unsigned int, Txid> pair = merkleBlock.vMatchedTxn[0];
    186 
    187-    BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"});
    188+    BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromHex("74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20").value());
    


    maflcko commented at 11:50 am on August 8, 2025:
    nit: You can use FromUint256 to retain the compile-time check here.
  31. maflcko commented at 11:51 am on August 8, 2025: member
    (nits are non-blocking)
  32. in src/txmempool.cpp:784 in a20724d926 outdated
    780@@ -781,7 +781,7 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
    781         AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
    782     }
    783     for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
    784-        uint256 hash = it->second->GetHash();
    785+        Txid hash = it->second->GetHash();
    


    stickies-v commented at 11:57 am on August 8, 2025:

    nit: we don’t need the iterator, so could modernize to:

     0diff --git a/src/txmempool.cpp b/src/txmempool.cpp
     1index d50c39593d..bbdcedd28f 100644
     2--- a/src/txmempool.cpp
     3+++ b/src/txmempool.cpp
     4@@ -780,12 +780,11 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
     5         for (const auto& input: tx.vin) mempoolDuplicate.SpendCoin(input.prevout);
     6         AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
     7     }
     8-    for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
     9-        Txid hash = it->second->GetHash();
    10-        indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
    11+    for (const auto& [_, next_tx] : mapNextTx) {
    12+        auto it2 = mapTx.find(next_tx->GetHash());
    13         const CTransaction& tx = it2->GetTx();
    14         assert(it2 != mapTx.end());
    15-        assert(&tx == it->second);
    16+        assert(&tx == next_tx);
    17     }
    18 
    19     assert(totalTxSize == checkTotal);
    
  33. in src/test/policyestimator_tests.cpp:80 in a20724d926 outdated
    76@@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
    77                                                                                       /*has_no_mempool_parents=*/true)};
    78                     m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
    79                 }
    80-                uint256 hash = tx.GetHash();
    81+                Txid hash = tx.GetHash();
    


    stickies-v commented at 12:19 pm on August 8, 2025:

    nit: just inline (+ 2 times below)

     0diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
     1index 3e16ac15e1..bbdd815fe4 100644
     2--- a/src/test/policyestimator_tests.cpp
     3+++ b/src/test/policyestimator_tests.cpp
     4@@ -77,8 +77,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
     5                                                                                       /*has_no_mempool_parents=*/true)};
     6                     m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
     7                 }
     8-                Txid hash = tx.GetHash();
     9-                txHashes[j].push_back(hash);
    10+                txHashes[j].push_back(tx.GetHash());
    11             }
    12         }
    13         //Create blocks where higher fee txs are included more often
    14@@ -178,8 +177,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
    15                                                                                       /*has_no_mempool_parents=*/true)};
    16                     m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
    17                 }
    18-                Txid hash = tx.GetHash();
    19-                txHashes[j].push_back(hash);
    20+                txHashes[j].push_back(tx.GetHash());
    21             }
    22         }
    23         {
    24@@ -242,8 +240,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
    25                                                                                       /*has_no_mempool_parents=*/true)};
    26                     m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
    27                 }
    28-                Txid hash = tx.GetHash();
    29-                CTransactionRef ptx = mpool.get(hash);
    30+                CTransactionRef ptx = mpool.get(tx.GetHash());
    31                 if (ptx)
    32                     block.push_back(ptx);
    33 
    
  34. in src/policy/rbf.cpp:65 in a20724d926 outdated
    61@@ -62,7 +62,7 @@ std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
    62                                                   CTxMemPool::setEntries& all_conflicts)
    63 {
    64     AssertLockHeld(pool.cs);
    65-    const uint256 txid = tx.GetHash();
    66+    const Txid txid = tx.GetHash();
    


    stickies-v commented at 1:28 pm on August 8, 2025:

    unnecessary allocation nit

     0diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp
     1index 40b82f5a5c..210b94915c 100644
     2--- a/src/policy/rbf.cpp
     3+++ b/src/policy/rbf.cpp
     4@@ -62,7 +62,6 @@ std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
     5                                                   CTxMemPool::setEntries& all_conflicts)
     6 {
     7     AssertLockHeld(pool.cs);
     8-    const Txid txid = tx.GetHash();
     9     uint64_t nConflictingCount = 0;
    10     for (const auto& mi : iters_conflicting) {
    11         nConflictingCount += mi->GetCountWithDescendants();
    12@@ -72,7 +71,7 @@ std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
    13         // times), but we just want to be conservative to avoid doing too much work.
    14         if (nConflictingCount > MAX_REPLACEMENT_CANDIDATES) {
    15             return strprintf("rejecting replacement %s; too many potential replacements (%d > %d)",
    16-                             txid.ToString(),
    17+                             tx.GetHash().ToString(),
    18                              nConflictingCount,
    19                              MAX_REPLACEMENT_CANDIDATES);
    20         }
    
  35. in src/index/txindex.cpp:47 in a20724d926 outdated
    48+bool TxIndex::DB::WriteTxs(const std::vector<std::pair<Txid, CDiskTxPos>>& v_pos)
    49 {
    50     CDBBatch batch(*this);
    51     for (const auto& tuple : v_pos) {
    52-        batch.Write(std::make_pair(DB_TXINDEX, tuple.first), tuple.second);
    53+        batch.Write(std::make_pair(DB_TXINDEX, tuple.first.ToUint256()), tuple.second);
    


    stickies-v commented at 1:57 pm on August 8, 2025:

    structured bindings nit:

     0diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
     1index a9bb90a697..11dd856e1b 100644
     2--- a/src/index/txindex.cpp
     3+++ b/src/index/txindex.cpp
     4@@ -43,8 +43,8 @@ bool TxIndex::DB::ReadTxPos(const Txid& txid, CDiskTxPos& pos) const
     5 bool TxIndex::DB::WriteTxs(const std::vector<std::pair<Txid, CDiskTxPos>>& v_pos)
     6 {
     7     CDBBatch batch(*this);
     8-    for (const auto& tuple : v_pos) {
     9-        batch.Write(std::make_pair(DB_TXINDEX, tuple.first.ToUint256()), tuple.second);
    10+    for (const auto& [txid, pos] : v_pos) {
    11+        batch.Write(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos);
    12     }
    13     return WriteBatch(batch);
    14 }
    
  36. in src/test/disconnected_transactions.cpp:25 in a20724d926 outdated
    21@@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(disconnectpool_memory_limits)
    22     // is within an expected range.
    23 
    24     // Overhead for the hashmap depends on number of buckets
    25-    std::unordered_map<uint256, CTransaction*, SaltedTxidHasher> temp_map;
    26+    std::unordered_map<uint256, CTransaction*, SaltedUint256Hasher> temp_map;
    


    stickies-v commented at 2:09 pm on August 8, 2025:

    Since DisconnectedBlockTransactions is Txid based, seems unusual to regress to uint256 here?

    0    std::unordered_map<Txid, CTransaction*, SaltedTxidHasher> temp_map;
    
  37. stickies-v approved
  38. stickies-v commented at 2:39 pm on August 8, 2025: contributor

    ACK a20724d926d5844168c6a13fa8293df8c8927efe

    Left nits mostly around making incremental improvements around code touched in this PR, but nothing blocking.

  39. kevkevinpal commented at 2:44 pm on August 8, 2025: contributor

    ACK a20724d


    I tested by doing the following

    To check for any usage of .uint256 instead of .ToUint256 grep -nri "\.uint256" ./src

    To check for any imports of util/transaction_identifier grep -nri "util/transaction_identifier" ./src


    One thing I did notice is that Txid::FromHex (introduced in #30482) is only used in the following locations, does it make sense to swap it out with uint256::FromHex? Not needed in this PR though

    0src/rest.cpp|820 col 21| auto hash{Txid::FromHex(hashStr)};
    1src/rest.cpp|909 col 29| auto txid{Txid::FromHex(txid_out.at(0))};
    2src/rpc/mining.cpp|356 col 29| if (auto txid{Txid::FromHex(str)}) {
    
  40. marcofleon commented at 2:50 pm on August 8, 2025: contributor
    I appreciate the reviews. Let me address the nits before this is merged, even if non-blocking. No rush, so might as well clean it up.
  41. cedwies commented at 12:41 pm on August 9, 2025: none

    Bit late to the party, but I would like to ask a question:

    Do we expect (present or future) any unordered_ containers keyed by GenTxid? From what I see, we already have salted hashers for Txid and Wtxid and use them in hashed containers. GenTxid (either Txid or Wtxid) uses and ordered map, so no hasher is needed. But if anyone later wants an unordered_map<GenTxid, ...> (e.g. for speed), they might convert back to uint256 or rely on std::hash (which weakens type-safety and DoS safety?). Would a proper SaltedGenTxidHasher (which mixes tag + bytes) make sense? Asking also for clarification whether I got the understanding right.

  42. refactor: Convert RPCs and `merkleblock` from uint256 to Txid 326f244724
  43. refactor: Convert `mini_miner` from uint256 to Txid aeb0f78330
  44. mempool, refactor: Convert uint256 to Txid f6c0d1d231
  45. policy, refactor: Convert uint256 to Txid d2ecd6815d
  46. 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`.
    9c24cda72e
  47. Remove implicit uint256 conversion and comparison 6f068f65de
  48. 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`.
    de0675f9de
  49. marcofleon force-pushed on Aug 11, 2025
  50. marcofleon commented at 5:19 pm on August 11, 2025: contributor

    Recent push addresses all comments from @maflcko and @stickies-v. Thanks!

    does it make sense to swap it out with uint256::FromHex @kevkevinpal It seems to be used in various tests as well, so it might be worth keeping for the time being.

    Do we expect (present or future) any unordered_ containers keyed by GenTxid? @cedwies Not that I know of, but if at some point we introduce a GenTxid unordered map, then yeah a hasher for GenTxids could make sense. I’m not too sure about the DoS attack potential if it only hashed by txhash and didn’t include type? But either way, I think we implement this if needed later on.

  51. stickies-v commented at 9:52 pm on August 11, 2025: contributor
    re-ACK de0675f9de5feae1f070840ad7218b1378fb880b, no changes since a20724d926d5844168c6a13fa8293df8c8927efe except address review nits.
  52. DrahtBot requested review from janb84 on Aug 11, 2025
  53. DrahtBot requested review from maflcko on Aug 11, 2025
  54. DrahtBot requested review from dergoegge on Aug 11, 2025
  55. janb84 commented at 10:51 am on August 12, 2025: contributor

    re ACK de0675f9de5feae1f070840ad7218b1378fb880b

    changes since last ACK:

    • Changes related to review Nits
  56. dergoegge approved
  57. dergoegge commented at 11:10 am on August 12, 2025: member
    re-ACK de0675f9de5feae1f070840ad7218b1378fb880b
  58. in src/rpc/rawtransaction.cpp:325 in 326f244724 outdated
    321@@ -322,10 +322,10 @@ static RPCHelpMan getrawtransaction()
    322     const NodeContext& node = EnsureAnyNodeContext(request.context);
    323     ChainstateManager& chainman = EnsureChainman(node);
    324 
    325-    uint256 hash = ParseHashV(request.params[0], "parameter 1");
    326+    auto txid{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))};
    


    theStack commented at 12:26 pm on August 13, 2025:
    nit, if you have to retouch: could rename this one to “txid” as well (and with s/parameter 3/blockhash/ below, we got them all)
  59. in src/merkleblock.cpp:136 in 326f244724 outdated
    132@@ -133,7 +133,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
    133     }
    134 }
    135 
    136-CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
    137+CPartialMerkleTree::CPartialMerkleTree(const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
    


    theStack commented at 12:41 pm on August 13, 2025:
    out-of-scope nit: the fact that the name vMatch is used for different types (vector of bool, vector of txids) in different methods is a bit confusing, probably worth it to rename if the file is touched again in the future
  60. theStack approved
  61. theStack commented at 12:44 pm on August 13, 2025: contributor
    Code-review ACK de0675f9de5feae1f070840ad7218b1378fb880b
  62. glozow merged this on Aug 13, 2025
  63. glozow closed this on Aug 13, 2025


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-08-24 09:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me