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

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

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

    <!--021abf342d371248e50ceaed478a90ca-->

    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.

    <!--174a7506f384e20aa4161008e828411d-->

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  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

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task lint: https://github.com/bitcoin/bitcoin/runs/47204972085</sub> <sub>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.</sub>

    <details><summary>Hints</summary>

    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.

    </details>

  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 ?

        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 ?

        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 ?

                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:

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/net_processing.cpp b/src/net_processing.cpp
    index 318b50f7fe..30074bff71 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<unsigned int, Txid> PairType;
    -                for (PairType& pair : merkleBlock.vMatchedTxn)
    -                    MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[pair.first]));
    +                for (auto& [tx_idx, _] : merkleBlock.vMatchedTxn)
    +                    MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[tx_idx]));
                 }
                 // else
                 // no response
    
    

    </details>

  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)

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
    index 18363ddebc..a37e4cf4b8 100644
    --- a/src/rpc/mempool.cpp
    +++ b/src/rpc/mempool.cpp
    @@ -483,10 +483,9 @@ static RPCHelpMan getmempoolancestors()
             UniValue o(UniValue::VOBJ);
             for (CTxMemPool::txiter ancestorIt : ancestors) {
                 const CTxMemPoolEntry &e = *ancestorIt;
    -            const Txid& 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;
         }
    @@ -549,10 +548,9 @@ static RPCHelpMan getmempooldescendants()
             UniValue o(UniValue::VOBJ);
             for (CTxMemPool::txiter descendantIt : setDescendants) {
                 const CTxMemPoolEntry &e = *descendantIt;
    -            const Txid& 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;
         }
    
    

    </details>

  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:

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/test/merkleblock_tests.cpp b/src/test/merkleblock_tests.cpp
    index 243214d329..48a61a3fc0 100644
    --- a/src/test/merkleblock_tests.cpp
    +++ b/src/test/merkleblock_tests.cpp
    @@ -46,10 +46,10 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_found)
         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);
     }
     
    
    

    </details>

  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

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/node/mini_miner.cpp b/src/node/mini_miner.cpp
    index c26355d832..a1c2edcb7b 100644
    --- a/src/node/mini_miner.cpp
    +++ b/src/node/mini_miner.cpp
    @@ -16,6 +16,7 @@
     
     #include <algorithm>
     #include <numeric>
    +#include <ranges>
     #include <utility>
     
     namespace node {
    @@ -61,12 +62,8 @@ MiniMiner::MiniMiner(const CTxMemPool& mempool, const std::vector<COutPoint>& ou
         if (m_requested_outpoints_by_txid.empty()) return;
     
         // Calculate the cluster and construct the entry map.
    -    std::vector<Txid> 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.
    
    

    </details>

  27. maflcko commented at 11:37 AM on August 8, 2025: member

    review ACK a20724d926d5844168c6a13fa8293df8c8927efe 🎰

    <details><summary>Show signature</summary>

    Signature:

    untrusted 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}"
    RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    trusted comment: review ACK a20724d926d5844168c6a13fa8293df8c8927efe 🎰
    owjWK+M1xuldjVXGuTv8u/HzGJbx30wzLvhYH1vVwALP65R1cq9YqC+QVHEwpFHaQTLY9RmEbhRByKiC25jNBQ==
    

    </details>

  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:

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/txmempool.cpp b/src/txmempool.cpp
    index d50c39593d..bbdcedd28f 100644
    --- a/src/txmempool.cpp
    +++ b/src/txmempool.cpp
    @@ -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<int>::max());
         }
    -    for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
    -        Txid hash = it->second->GetHash();
    -        indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
    +    for (const auto& [_, next_tx] : mapNextTx) {
    +        auto it2 = mapTx.find(next_tx->GetHash());
             const CTransaction& tx = it2->GetTx();
             assert(it2 != mapTx.end());
    -        assert(&tx == it->second);
    +        assert(&tx == next_tx);
         }
     
         assert(totalTxSize == checkTotal);
    
    

    </details>

  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)

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
    index 3e16ac15e1..bbdd815fe4 100644
    --- a/src/test/policyestimator_tests.cpp
    +++ b/src/test/policyestimator_tests.cpp
    @@ -77,8 +77,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
                                                                                           /*has_no_mempool_parents=*/true)};
                         m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
                     }
    -                Txid 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());
                     }
    -                Txid 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());
                     }
    -                Txid hash = tx.GetHash();
    -                CTransactionRef ptx = mpool.get(hash);
    +                CTransactionRef ptx = mpool.get(tx.GetHash());
                     if (ptx)
                         block.push_back(ptx);
     
    
    

    </details>

  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

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp
    index 40b82f5a5c..210b94915c 100644
    --- a/src/policy/rbf.cpp
    +++ b/src/policy/rbf.cpp
    @@ -62,7 +62,6 @@ std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
                                                       CTxMemPool::setEntries& all_conflicts)
     {
         AssertLockHeld(pool.cs);
    -    const Txid txid = tx.GetHash();
         uint64_t nConflictingCount = 0;
         for (const auto& mi : iters_conflicting) {
             nConflictingCount += mi->GetCountWithDescendants();
    @@ -72,7 +71,7 @@ std::optional<std::string> 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);
             }
    
    

    </details>

  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:

    <details> <summary>git diff on a20724d926</summary>

    diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
    index a9bb90a697..11dd856e1b 100644
    --- a/src/index/txindex.cpp
    +++ b/src/index/txindex.cpp
    @@ -43,8 +43,8 @@ bool TxIndex::DB::ReadTxPos(const Txid& txid, CDiskTxPos& pos) const
     bool TxIndex::DB::WriteTxs(const std::vector<std::pair<Txid, CDiskTxPos>>& v_pos)
     {
         CDBBatch batch(*this);
    -    for (const auto& tuple : v_pos) {
    -        batch.Write(std::make_pair(DB_TXINDEX, tuple.first.ToUint256()), tuple.second);
    +    for (const auto& [txid, pos] : v_pos) {
    +        batch.Write(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos);
         }
         return WriteBatch(batch);
     }
    
    

    </details>

  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?

        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

    src/rest.cpp|820 col 21| auto hash{Txid::FromHex(hashStr)};
    src/rest.cpp|909 col 29| auto txid{Txid::FromHex(txid_out.at(0))};
    src/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: 2026-04-18 06:12 UTC

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