Convert remaining instances of uint256 to Txid

These remaining miscellaneous changes were discovered by commenting
out the implicit conversion in `transaction_identifier`.
This commit is contained in:
marcofleon 2025-04-01 16:05:45 +01:00
parent 339685e1ab
commit 13f95efab5
21 changed files with 83 additions and 52 deletions

View file

@ -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;
}

View file

@ -68,7 +68,7 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
std::vector<uint256> 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<uint256> TransactionMerklePath(const CBlock& block, uint32_t positio
std::vector<uint256> 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);
}

View file

@ -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;

View file

@ -9,6 +9,7 @@
#include <index/disktxpos.h>
#include <logging.h>
#include <node/blockstorage.h>
#include <util/transaction_identifier.h>
#include <validation.h>
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<std::pair<uint256, CDiskTxPos>>& v_pos);
[[nodiscard]] bool WriteTxs(const std::vector<std::pair<Txid, CDiskTxPos>>& 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<std::pair<uint256, CDiskTxPos>>& v_pos)
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), tuple.second);
batch.Write(std::make_pair(DB_TXINDEX, tuple.first.ToUint256()), tuple.second);
}
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<std::pair<uint256, CDiskTxPos>> vPos;
std::vector<std::pair<Txid, CDiskTxPos>> 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)) {

View file

@ -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.

View file

@ -98,7 +98,7 @@ static void ApplyHash(T& hash_obj, const Txid& hash, const std::map<uint32_t, Co
}
}
static void ApplyStats(CCoinsStats& stats, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
static void ApplyStats(CCoinsStats& stats, const std::map<uint32_t, Coin>& 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);
}

View file

@ -41,7 +41,7 @@ private:
const size_t m_max_mem_usage;
std::list<CTransactionRef> queuedTx;
using TxList = decltype(queuedTx);
std::unordered_map<uint256, TxList::iterator, SaltedTxidHasher> iters_by_txid;
std::unordered_map<Txid, TxList::iterator, SaltedTxidHasher> iters_by_txid;
/** Trim the earliest-added entries until we are within memory bounds. */
std::vector<CTransactionRef> LimitMemoryUsage();

View file

@ -44,11 +44,11 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std:
vMatch.push_back(true);
} else if (filter && filter->IsRelevantAndUpdate(*block.vtx[i])) {
vMatch.push_back(true);
vMatchedTxn.emplace_back(i, hash);
vMatchedTxn.emplace_back(i, hash.ToUint256());
} else {
vMatch.push_back(false);
}
vHashes.push_back(hash);
vHashes.push_back(hash.ToUint256());
}
txn = CPartialMerkleTree(vHashes, vMatch);

View file

@ -2992,7 +2992,7 @@ std::optional<node::PackageToValidate> 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);
@ -4228,12 +4228,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);
@ -4244,13 +4243,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);
}
}

View file

@ -59,9 +59,9 @@ static uint256 ComputeModifiedMerkleRoot(const CMutableTransaction& cb, const CB
{
std::vector<uint256> 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));
}

View file

@ -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<uint256, CTransaction*, SaltedTxidHasher> temp_map;
std::unordered_map<uint256, CTransaction*, SaltedUint256Hasher> temp_map;
temp_map.reserve(1);
const size_t MAP_1{memusage::DynamicUsage(temp_map)};
temp_map.reserve(100);

View file

@ -129,7 +129,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;
}

View file

@ -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<CTransactionRef>::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<uint256> newBranch = TransactionMerklePath(block, mtx);
std::vector<uint256> 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<uint256> 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);

View file

@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
uint256 merkleRoot1 = BlockMerkleRoot(block);
std::vector<uint256> vTxid(nTx, uint256());
for (unsigned int j=0; j<nTx; j++)
vTxid[j] = block.vtx[j]->GetHash();
vTxid[j] = block.vtx[j]->GetHash().ToUint256();
int nHeight = 1, nTx_ = nTx;
while (nTx_ > 1) {
nTx_ = (nTx_+1)/2;

View file

@ -628,3 +628,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();
}

View file

@ -291,6 +291,8 @@ inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& 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);
// @}
/**

View file

@ -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);
}

View file

@ -7,6 +7,10 @@
#include <span.h>
#include <util/hasher.h>
SaltedUint256Hasher::SaltedUint256Hasher() :
k0{FastRandomContext().rand64()},
k1{FastRandomContext().rand64()} {}
SaltedTxidHasher::SaltedTxidHasher() :
k0{FastRandomContext().rand64()},
k1{FastRandomContext().rand64()} {}

View file

@ -11,9 +11,24 @@
#include <span.h>
#include <uint256.h>
#include <concepts>
#include <cstdint>
#include <cstring>
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,8 +38,10 @@ private:
public:
SaltedTxidHasher();
size_t operator()(const uint256& txid) const {
return SipHashUint256(k0, k1, txid);
template <typename T>
requires std::same_as<T, Txid> || std::same_as<T, Wtxid>
size_t operator()(const T& txid) const {
return SipHashUint256(k0, k1, txid.ToUint256());
}
};
@ -47,7 +64,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);
}
};

View file

@ -1257,7 +1257,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
@ -1304,7 +1304,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(),
@ -1716,7 +1716,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
// The package must be 1 child with all of its unconfirmed parents. The package is expected to
// be sorted, so the last transaction is the child.
const auto& child = package.back();
std::unordered_set<uint256, SaltedTxidHasher> unconfirmed_parent_txids;
std::unordered_set<Txid, SaltedTxidHasher> unconfirmed_parent_txids;
std::transform(package.cbegin(), package.cend() - 1,
std::inserter(unconfirmed_parent_txids, unconfirmed_parent_txids.end()),
[](const auto& tx) { return tx->GetHash(); });

View file

@ -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);
}