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`.
This commit is contained in:
marcofleon committed 2025-08-11 16:47:43 +01:00
1 parent d2ecd6815d
commit 9c24cda72e
25 files changed
+117 -69

No files matched your search

+1 -1
View File
@@ -42,7 +42,7 @@ void CBlockHeaderAndShortTxIDs::FillShortTxIDSelector() const {
uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const Wtxid& wtxid) const { uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const Wtxid& wtxid) const {
static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids calculation assumes 6-byte shorttxids"); 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<CTransactionRef>& extra_txn) { ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<CTransactionRef>& extra_txn) {
+3 -3
View File
@@ -68,7 +68,7 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
std::vector<uint256> leaves; std::vector<uint256> leaves;
leaves.resize(block.vtx.size()); leaves.resize(block.vtx.size());
for (size_t s = 0; s < block.vtx.size(); s++) { 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); return ComputeMerkleRoot(std::move(leaves), mutated);
} }
@@ -79,7 +79,7 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
leaves.resize(block.vtx.size()); leaves.resize(block.vtx.size());
leaves[0].SetNull(); // The witness hash of the coinbase is 0. leaves[0].SetNull(); // The witness hash of the coinbase is 0.
for (size_t s = 1; s < block.vtx.size(); s++) { 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); return ComputeMerkleRoot(std::move(leaves), mutated);
} }
@@ -185,7 +185,7 @@ std::vector<uint256> TransactionMerklePath(const CBlock& block, uint32_t positio
std::vector<uint256> leaves; std::vector<uint256> leaves;
leaves.resize(block.vtx.size()); leaves.resize(block.vtx.size());
for (size_t s = 0; s < block.vtx.size(); s++) { 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); return ComputeMerklePath(leaves, position);
} }
+1 -1
View File
@@ -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 /** 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 * required to guarantee that we won't reuse this object with the same
* SaltedTxidHasher for another sync. */ * SaltedUint256Hasher for another sync. */
void HeadersSyncState::Finalize() void HeadersSyncState::Finalize()
{ {
Assume(m_download_state != State::FINAL); Assume(m_download_state != State::FINAL);
+1 -1
View File
@@ -224,7 +224,7 @@ private:
arith_uint256 m_current_chain_work; arith_uint256 m_current_chain_work;
/** m_hasher is a salted hasher for making our 1-bit commitments to headers we've seen. */ /** 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. */ /** A queue of commitment bits, created during the 1st phase, and verified during the 2nd. */
bitdeque<> m_header_commitments; bitdeque<> m_header_commitments;
+10 -9
View File
@@ -9,6 +9,7 @@
#include <index/disktxpos.h> #include <index/disktxpos.h>
#include <logging.h> #include <logging.h>
#include <node/blockstorage.h> #include <node/blockstorage.h>
#include <util/transaction_identifier.h>
#include <validation.h> #include <validation.h>
constexpr uint8_t DB_TXINDEX{'t'}; 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 /// Read the disk location of the transaction data with the given hash. Returns false if the
/// transaction hash is not indexed. /// 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. /// 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) : 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) 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); CDBBatch batch(*this);
for (const auto& tuple : v_pos) { for (const auto& [txid, pos] : v_pos) {
batch.Write(std::make_pair(DB_TXINDEX, tuple.first), tuple.second); batch.Write(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos);
} }
return WriteBatch(batch); return WriteBatch(batch);
} }
@@ -61,7 +62,7 @@ bool TxIndex::CustomAppend(const interfaces::BlockInfo& block)
assert(block.data); assert(block.data);
CDiskTxPos pos({block.file_number, block.data_pos}, GetSizeOfCompactSize(block.data->vtx.size())); 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()); vPos.reserve(block.data->vtx.size());
for (const auto& tx : block.data->vtx) { for (const auto& tx : block.data->vtx) {
vPos.emplace_back(tx->GetHash(), pos); 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; } 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; CDiskTxPos postx;
if (!m_db->ReadTxPos(tx_hash, postx)) { if (!m_db->ReadTxPos(tx_hash, postx)) {
+1 -1
View File
@@ -42,7 +42,7 @@ public:
/// @param[out] block_hash The hash of the block the transaction is found in. /// @param[out] block_hash The hash of the block the transaction is found in.
/// @param[out] tx The transaction itself. /// @param[out] tx The transaction itself.
/// @return true if transaction is found, false otherwise /// @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. /// The global transaction index, used in GetTransaction. May be null.
+3 -3
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()); assert(!outputs.empty());
stats.nTransactions++; stats.nTransactions++;
@@ -126,7 +126,7 @@ static bool ComputeUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, c
Coin coin; Coin coin;
if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
if (!outputs.empty() && key.hash != prevkey) { if (!outputs.empty() && key.hash != prevkey) {
ApplyStats(stats, prevkey, outputs); ApplyStats(stats, outputs);
ApplyHash(hash_obj, prevkey, outputs); ApplyHash(hash_obj, prevkey, outputs);
outputs.clear(); outputs.clear();
} }
@@ -140,7 +140,7 @@ static bool ComputeUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, c
pcursor->Next(); pcursor->Next();
} }
if (!outputs.empty()) { if (!outputs.empty()) {
ApplyStats(stats, prevkey, outputs); ApplyStats(stats, outputs);
ApplyHash(hash_obj, prevkey, outputs); ApplyHash(hash_obj, prevkey, outputs);
} }
+1 -1
View File
@@ -41,7 +41,7 @@ private:
const size_t m_max_mem_usage; const size_t m_max_mem_usage;
std::list<CTransactionRef> queuedTx; std::list<CTransactionRef> queuedTx;
using TxList = decltype(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. */ /** Trim the earliest-added entries until we are within memory bounds. */
std::vector<CTransactionRef> LimitMemoryUsage(); std::vector<CTransactionRef> LimitMemoryUsage();
+8 -9
View File
@@ -3030,7 +3030,7 @@ std::optional<node::PackageToValidate> PeerManagerImpl::ProcessInvalidTx(NodeId
AddToCompactExtraTransactions(ptx); AddToCompactExtraTransactions(ptx);
} }
for (const Txid& parent_txid : unique_parents) { for (const Txid& parent_txid : unique_parents) {
if (peer) AddKnownTx(*peer, parent_txid); if (peer) AddKnownTx(*peer, parent_txid.ToUint256());
} }
MaybePunishNodeForTx(nodeid, state); MaybePunishNodeForTx(nodeid, state);
@@ -4280,12 +4280,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
CTransactionRef ptx; CTransactionRef ptx;
vRecv >> TX_WITH_WITNESS(ptx); vRecv >> TX_WITH_WITNESS(ptx);
const CTransaction& tx = *ptx;
const uint256& txid = ptx->GetHash(); const Txid& txid = ptx->GetHash();
const uint256& wtxid = ptx->GetWitnessHash(); 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); AddKnownTx(*peer, hash);
LOCK2(cs_main, m_tx_download_mutex); 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 // Always relay transactions received from peers with forcerelay
// permission, even if they were already in the mempool, allowing // permission, even if they were already in the mempool, allowing
// the node to function as a gateway for nodes hidden behind it. // 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", 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 { } else {
LogPrintf("Force relaying tx %s (wtxid=%s) from peer=%d\n", LogPrintf("Force relaying tx %s (wtxid=%s) from peer=%d\n",
tx.GetHash().ToString(), tx.GetWitnessHash().ToString(), pfrom.GetId()); txid.ToString(), wtxid.ToString(), pfrom.GetId());
RelayTransaction(tx.GetHash(), tx.GetWitnessHash()); RelayTransaction(txid, wtxid);
} }
} }
+14 -14
View File
@@ -104,8 +104,8 @@ void TxDownloadManagerImpl::BlockConnected(const std::shared_ptr<const CBlock>&
if (ptx->HasWitness()) { if (ptx->HasWitness()) {
RecentConfirmedTransactionsFilter().insert(ptx->GetWitnessHash().ToUint256()); RecentConfirmedTransactionsFilter().insert(ptx->GetWitnessHash().ToUint256());
} }
m_txrequest.ForgetTxHash(ptx->GetHash()); m_txrequest.ForgetTxHash(ptx->GetHash().ToUint256());
m_txrequest.ForgetTxHash(ptx->GetWitnessHash()); 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. // 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. // No-op if the tx is not in txrequest.
m_txrequest.ForgetTxHash(tx->GetHash()); m_txrequest.ForgetTxHash(tx->GetHash().ToUint256());
m_txrequest.ForgetTxHash(tx->GetWitnessHash()); m_txrequest.ForgetTxHash(tx->GetWitnessHash().ToUint256());
m_orphanage->AddChildrenToWorkSet(*tx, m_opts.m_rng); 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. // 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 // Search by txid and, if the tx has a witness, wtxid
std::vector<NodeId> orphan_resolution_candidates{nodeid}; std::vector<NodeId> orphan_resolution_candidates{nodeid};
m_txrequest.GetCandidatePeers(ptx->GetHash(), orphan_resolution_candidates); m_txrequest.GetCandidatePeers(ptx->GetHash().ToUint256(), orphan_resolution_candidates);
if (ptx->HasWitness()) m_txrequest.GetCandidatePeers(ptx->GetWitnessHash(), orphan_resolution_candidates); if (ptx->HasWitness()) m_txrequest.GetCandidatePeers(ptx->GetWitnessHash().ToUint256(), orphan_resolution_candidates);
for (const auto& nodeid : orphan_resolution_candidates) { for (const auto& nodeid : orphan_resolution_candidates) {
if (MaybeAddOrphanResolutionCandidate(unique_parents, ptx->GetWitnessHash(), nodeid, now)) { 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. // 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.GetHash().ToUint256());
m_txrequest.ForgetTxHash(tx.GetWitnessHash()); m_txrequest.ForgetTxHash(tx.GetWitnessHash().ToUint256());
} else { } else {
unique_parents.clear(); unique_parents.clear();
LogDebug(BCLog::MEMPOOL, "not keeping orphan with rejected parents %s (wtxid=%s)\n", 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. // from any of our non-wtxidrelay peers.
RecentRejectsFilter().insert(tx.GetHash().ToUint256()); RecentRejectsFilter().insert(tx.GetHash().ToUint256());
RecentRejectsFilter().insert(tx.GetWitnessHash().ToUint256()); RecentRejectsFilter().insert(tx.GetWitnessHash().ToUint256());
m_txrequest.ForgetTxHash(tx.GetHash()); m_txrequest.ForgetTxHash(tx.GetHash().ToUint256());
m_txrequest.ForgetTxHash(tx.GetWitnessHash()); m_txrequest.ForgetTxHash(tx.GetWitnessHash().ToUint256());
} }
} }
} else if (state.GetResult() == TxValidationResult::TX_WITNESS_STRIPPED) { } else if (state.GetResult() == TxValidationResult::TX_WITNESS_STRIPPED) {
@@ -467,7 +467,7 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction
} else { } else {
RecentRejectsFilter().insert(ptx->GetWitnessHash().ToUint256()); 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, // If the transaction failed for TX_INPUTS_NOT_STANDARD,
// then we know that the witness was irrelevant to the policy // then we know that the witness was irrelevant to the policy
// failure, since this check depends only on the txid // failure, since this check depends only on the txid
@@ -480,7 +480,7 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction
// rolling bloom filter. // rolling bloom filter.
if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && ptx->HasWitness()) { if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && ptx->HasWitness()) {
RecentRejectsFilter().insert(ptx->GetHash().ToUint256()); RecentRejectsFilter().insert(ptx->GetHash().ToUint256());
m_txrequest.ForgetTxHash(ptx->GetHash()); m_txrequest.ForgetTxHash(ptx->GetHash().ToUint256());
} }
} }
@@ -508,8 +508,8 @@ std::pair<bool, std::optional<PackageToValidate>> TxDownloadManagerImpl::Receive
const Wtxid& wtxid = ptx->GetWitnessHash(); const Wtxid& wtxid = ptx->GetWitnessHash();
// Mark that we have received a response // Mark that we have received a response
m_txrequest.ReceivedResponse(nodeid, txid); m_txrequest.ReceivedResponse(nodeid, txid.ToUint256());
if (ptx->HasWitness()) m_txrequest.ReceivedResponse(nodeid, wtxid); if (ptx->HasWitness()) m_txrequest.ReceivedResponse(nodeid, wtxid.ToUint256());
// First check if we should drop this tx. // First check if we should drop this tx.
// We do the AlreadyHaveTx() check using wtxid, rather than txid - in the // We do the AlreadyHaveTx() check using wtxid, rather than txid - in the
+2 -2
View File
@@ -59,9 +59,9 @@ static uint256 ComputeModifiedMerkleRoot(const CMutableTransaction& cb, const CB
{ {
std::vector<uint256> leaves; std::vector<uint256> leaves;
leaves.resize(block.vtx.size()); leaves.resize(block.vtx.size());
leaves[0] = cb.GetHash(); leaves[0] = cb.GetHash().ToUint256();
for (size_t s = 1; s < block.vtx.size(); ++s) { 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)); return ComputeMerkleRoot(std::move(leaves));
} }
+1 -1
View File
@@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(disconnectpool_memory_limits)
// is within an expected range. // is within an expected range.
// Overhead for the hashmap depends on number of buckets // Overhead for the hashmap depends on number of buckets
std::unordered_map<uint256, CTransaction*, SaltedTxidHasher> temp_map; std::unordered_map<Txid, CTransaction*, SaltedTxidHasher> temp_map;
temp_map.reserve(1); temp_map.reserve(1);
const size_t MAP_1{memusage::DynamicUsage(temp_map)}; const size_t MAP_1{memusage::DynamicUsage(temp_map)};
temp_map.reserve(100); temp_map.reserve(100);
+2 -2
View File
@@ -19,7 +19,7 @@ uint256 ComputeMerkleRootFromPath(const CBlock& block, uint32_t position, const
throw std::out_of_range("Position out of range"); 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) { for (const uint256& sibling : merkle_path) {
if (position % 2 == 0) { if (position % 2 == 0) {
@@ -47,7 +47,7 @@ FUZZ_TARGET(merkle)
tx_hashes.reserve(num_txs); tx_hashes.reserve(num_txs);
for (size_t i = 0; i < num_txs; ++i) { 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 // Test ComputeMerkleRoot
+1 -1
View File
@@ -139,7 +139,7 @@ CBlock ConsumeBlock(FuzzedDataProvider& fuzzed_data_provider, const uint256& pre
tx.vout[0].nValue = 0; tx.vout[0].nValue = 0;
tx.vin[0].scriptSig.resize(2); tx.vin[0].scriptSig.resize(2);
block.vtx.push_back(MakeTransactionRef(tx)); block.vtx.push_back(MakeTransactionRef(tx));
block.hashMerkleRoot = block.vtx[0]->GetHash(); block.hashMerkleRoot = block.vtx[0]->GetHash().ToUint256();
return block; return block;
} }
+4 -4
View File
@@ -29,7 +29,7 @@ static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::ve
vMerkleTree.clear(); vMerkleTree.clear();
vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. 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) 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; int j = 0;
bool mutated = false; bool mutated = false;
for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) 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> newBranch = TransactionMerklePath(block, mtx);
std::vector<uint256> oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx); std::vector<uint256> oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx);
BOOST_CHECK(oldBranch == newBranch); 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; mtx.nLockTime = 0;
block.vtx[0] = MakeTransactionRef(std::move(mtx)); block.vtx[0] = MakeTransactionRef(std::move(mtx));
uint256 root = BlockMerkleRoot(block, &mutated); 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); BOOST_CHECK_EQUAL(mutated, false);
} }
@@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(merkle_test_BlockWitness)
std::vector<uint256> hashes; std::vector<uint256> hashes;
hashes.resize(block.vtx.size()); hashes.resize(block.vtx.size());
hashes[0].SetNull(); hashes[0].SetNull();
hashes[1] = block.vtx[1]->GetHash(); hashes[1] = block.vtx[1]->GetHash().ToUint256();
uint256 merkleRootofHashes = ComputeMerkleRoot(hashes); uint256 merkleRootofHashes = ComputeMerkleRoot(hashes);
+8
View File
@@ -629,3 +629,11 @@ std::ostream& operator<<(std::ostream& os, const uint256& num)
{ {
return os << num.ToString(); 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();
}
+2
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 arith_uint256& num);
std::ostream& operator<<(std::ostream& os, const uint160& 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 uint256& num);
std::ostream& operator<<(std::ostream& os, const Txid& txid);
std::ostream& operator<<(std::ostream& os, const Wtxid& wtxid);
// @} // @}
/** /**
+4 -4
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 // Block with a single coinbase tx is mutated if the merkle root is not
// equal to the coinbase tx's hash. // equal to the coinbase tx's hash.
block.vtx.push_back(create_coinbase_tx()); 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)); 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)); BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
// Block with two transactions is mutated if the merkle root does not // 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.resize(1);
mtx.vout[0].scriptPubKey.resize(4); mtx.vout[0].scriptPubKey.resize(4);
block.vtx.push_back(MakeTransactionRef(mtx)); 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(block.vtx.back()->IsCoinBase());
assert(GetSerializeSize(TX_NO_WITNESS(block.vtx.back())) == 64); assert(GetSerializeSize(TX_NO_WITNESS(block.vtx.back())) == 64);
} }
@@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(block_malleation)
HashWriter hasher; HashWriter hasher;
hasher.write(tx1.GetHash()); hasher.write(tx1.GetHash());
hasher.write(tx2.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). // Verify that tx3 is 64 bytes in size (without witness).
assert(GetSerializeSize(TX_NO_WITNESS(tx3)) == 64); assert(GetSerializeSize(TX_NO_WITNESS(tx3)) == 64);
} }
+1 -1
View File
@@ -313,7 +313,7 @@ public:
boost::multi_index::hashed_unique< boost::multi_index::hashed_unique<
boost::multi_index::tag<index_by_wtxid>, boost::multi_index::tag<index_by_wtxid>,
mempoolentry_wtxid, mempoolentry_wtxid,
SaltedTxidHasher SaltedWtxidHasher
>, >,
// sorted by fee rate // sorted by fee rate
boost::multi_index::ordered_non_unique< boost::multi_index::ordered_non_unique<
+8
View File
@@ -7,10 +7,18 @@
#include <span.h> #include <span.h>
#include <util/hasher.h> #include <util/hasher.h>
SaltedUint256Hasher::SaltedUint256Hasher() :
k0{FastRandomContext().rand64()},
k1{FastRandomContext().rand64()} {}
SaltedTxidHasher::SaltedTxidHasher() : SaltedTxidHasher::SaltedTxidHasher() :
k0{FastRandomContext().rand64()}, k0{FastRandomContext().rand64()},
k1{FastRandomContext().rand64()} {} k1{FastRandomContext().rand64()} {}
SaltedWtxidHasher::SaltedWtxidHasher() :
k0{FastRandomContext().rand64()},
k1{FastRandomContext().rand64()} {}
SaltedOutpointHasher::SaltedOutpointHasher(bool deterministic) : SaltedOutpointHasher::SaltedOutpointHasher(bool deterministic) :
k0{deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64()}, k0{deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64()},
k1{deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} k1{deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()}
+33 -3
View File
@@ -11,9 +11,24 @@
#include <span.h> #include <span.h>
#include <uint256.h> #include <uint256.h>
#include <concepts>
#include <cstdint> #include <cstdint>
#include <cstring> #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 class SaltedTxidHasher
{ {
private: private:
@@ -23,11 +38,26 @@ private:
public: public:
SaltedTxidHasher(); SaltedTxidHasher();
size_t operator()(const uint256& txid) const { size_t operator()(const Txid& txid) const {
return SipHashUint256(k0, k1, txid); 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 class SaltedOutpointHasher
{ {
private: private:
@@ -47,7 +77,7 @@ public:
* @see https://gcc.gnu.org/onlinedocs/gcc-13.2.0/libstdc++/manual/manual/unordered_associative.html * @see https://gcc.gnu.org/onlinedocs/gcc-13.2.0/libstdc++/manual/manual/unordered_associative.html
*/ */
size_t operator()(const COutPoint& id) const noexcept { 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);
} }
}; };
+2 -2
View File
@@ -1275,7 +1275,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
AssertLockHeld(m_pool.cs); AssertLockHeld(m_pool.cs);
const CTransaction& tx = *ws.m_ptx; const CTransaction& tx = *ws.m_ptx;
const uint256& hash = ws.m_hash; const Txid& hash = ws.m_hash;
TxValidationState& state = ws.m_state; TxValidationState& state = ws.m_state;
// Check again against the current block tip's script verification // 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}; const bool replaced_with_tx{m_subpackage.m_changeset->GetTxCount() == 1};
if (replaced_with_tx) { if (replaced_with_tx) {
const CTransaction& tx = m_subpackage.m_changeset->GetAddedTxn(0); 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)", log_string += strprintf("New tx %s (wtxid=%s, fees=%s, vsize=%s)",
tx.GetHash().ToString(), tx.GetHash().ToString(),
tx.GetWitnessHash().ToString(), tx.GetWitnessHash().ToString(),
+1 -1
View File
@@ -327,7 +327,7 @@ CoinsResult AvailableCoins(const CWallet& wallet,
std::set<Txid> trusted_parents; std::set<Txid> trusted_parents;
// Cache for whether each tx passes the tx level checks (first bool), and whether the transaction is "safe" (second bool) // Cache for whether each tx passes the tx level checks (first bool), and whether the transaction is "safe" (second bool)
std::unordered_map<uint256, std::pair<bool, bool>, SaltedTxidHasher> tx_safe_cache; std::unordered_map<Txid, std::pair<bool, bool>, SaltedTxidHasher> tx_safe_cache;
for (const auto& [outpoint, txo] : wallet.GetTXOs()) { for (const auto& [outpoint, txo] : wallet.GetTXOs()) {
const CWalletTx& wtx = txo.GetWalletTx(); const CWalletTx& wtx = txo.GetWalletTx();
const CTxOut& output = txo.GetTxOut(); const CTxOut& output = txo.GetTxOut();
+1 -1
View File
@@ -2319,7 +2319,7 @@ util::Result<void> CWallet::RemoveTxs(WalletBatch& batch, std::vector<Txid>& txs
for (const auto& txin : it->second.tx->vin) for (const auto& txin : it->second.tx->vin)
mapTxSpends.erase(txin.prevout); mapTxSpends.erase(txin.prevout);
for (unsigned int i = 0; i < it->second.tx->vout.size(); ++i) { 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); mapWallet.erase(it);
NotifyTransactionChanged(hash, CT_DELETED); NotifyTransactionChanged(hash, CT_DELETED);
+4 -4
View File
@@ -230,7 +230,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) 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); LogDebug(BCLog::ZMQ, "Publish hashtx %s to %s\n", hash.GetHex(), this->address);
uint8_t data[32]; uint8_t data[32];
for (unsigned int i = 0; i < 32; i++) { for (unsigned int i = 0; i < 32; i++) {
@@ -254,7 +254,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) 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); LogDebug(BCLog::ZMQ, "Publish rawtx %s to %s\n", hash.GetHex(), this->address);
DataStream ss; DataStream ss;
ss << TX_WITH_WITNESS(transaction); 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) 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); 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); return SendSequenceMsg(*this, hash, /* Mempool (A)cceptance */ 'A', mempool_sequence);
} }
bool CZMQPublishSequenceNotifier::NotifyTransactionRemoval(const CTransaction &transaction, uint64_t 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); 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); return SendSequenceMsg(*this, hash, /* Mempool (R)emoval */ 'R', mempool_sequence);
} }