From ed70e6501648466b9ca91a39b83775363e9a726d Mon Sep 17 00:00:00 2001 From: dergoegge Date: Wed, 19 Jul 2023 15:37:29 +0200 Subject: [PATCH] Introduce types for txids & wtxids --- src/Makefile.am | 1 + src/net_processing.cpp | 29 +++++++------ src/primitives/transaction.cpp | 16 ++++---- src/primitives/transaction.h | 15 +++---- src/test/fuzz/package_eval.cpp | 2 +- src/test/fuzz/tx_pool.cpp | 4 +- src/util/transaction_identifier.h | 67 +++++++++++++++++++++++++++++++ src/validation.cpp | 4 +- src/wallet/transaction.h | 4 +- 9 files changed, 109 insertions(+), 33 deletions(-) create mode 100644 src/util/transaction_identifier.h diff --git a/src/Makefile.am b/src/Makefile.am index 8905c0ad1cd..8508d13b349 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -328,6 +328,7 @@ BITCOIN_CORE_H = \ util/time.h \ util/tokenpipe.h \ util/trace.h \ + util/transaction_identifier.h \ util/translation.h \ util/types.h \ util/ui_change_type.h \ diff --git a/src/net_processing.cpp b/src/net_processing.cpp index dea257f7cc5..58bf3ec5d1e 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1851,9 +1851,9 @@ void PeerManagerImpl::BlockConnected(const std::shared_ptr& pblock { LOCK(m_recent_confirmed_transactions_mutex); for (const auto& ptx : pblock->vtx) { - m_recent_confirmed_transactions.insert(ptx->GetHash()); + m_recent_confirmed_transactions.insert(ptx->GetHash().ToUint256()); if (ptx->HasWitness()) { - m_recent_confirmed_transactions.insert(ptx->GetWitnessHash()); + m_recent_confirmed_transactions.insert(ptx->GetWitnessHash().ToUint256()); } } } @@ -2967,7 +2967,7 @@ bool PeerManagerImpl::ProcessOrphanTx(Peer& peer) // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034 // for concerns around weakening security of unupgraded nodes // if we start doing this too early. - m_recent_rejects.insert(porphanTx->GetWitnessHash()); + m_recent_rejects.insert(porphanTx->GetWitnessHash().ToUint256()); // If the transaction failed for TX_INPUTS_NOT_STANDARD, // then we know that the witness was irrelevant to the policy // failure, since this check depends only on the txid @@ -2979,7 +2979,7 @@ bool PeerManagerImpl::ProcessOrphanTx(Peer& peer) if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && porphanTx->HasWitness()) { // We only add the txid if it differs from the wtxid, to // avoid wasting entries in the rolling bloom filter. - m_recent_rejects.insert(porphanTx->GetHash()); + m_recent_rejects.insert(porphanTx->GetHash().ToUint256()); } } m_orphanage.EraseTx(orphanHash); @@ -4230,8 +4230,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, // regardless of what witness is provided, we will not accept // this, so we don't need to allow for redownload of this txid // from any of our non-wtxidrelay peers. - m_recent_rejects.insert(tx.GetHash()); - m_recent_rejects.insert(tx.GetWitnessHash()); + m_recent_rejects.insert(tx.GetHash().ToUint256()); + m_recent_rejects.insert(tx.GetWitnessHash().ToUint256()); m_txrequest.ForgetTxHash(tx.GetHash()); m_txrequest.ForgetTxHash(tx.GetWitnessHash()); } @@ -4250,7 +4250,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034 // for concerns around weakening security of unupgraded nodes // if we start doing this too early. - m_recent_rejects.insert(tx.GetWitnessHash()); + m_recent_rejects.insert(tx.GetWitnessHash().ToUint256()); m_txrequest.ForgetTxHash(tx.GetWitnessHash()); // If the transaction failed for TX_INPUTS_NOT_STANDARD, // then we know that the witness was irrelevant to the policy @@ -4261,7 +4261,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, // transactions are later received (resulting in // parent-fetching by txid via the orphan-handling logic). if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.HasWitness()) { - m_recent_rejects.insert(tx.GetHash()); + m_recent_rejects.insert(tx.GetHash().ToUint256()); m_txrequest.ForgetTxHash(tx.GetHash()); } if (RecursiveDynamicUsage(*ptx) < 100000) { @@ -5694,9 +5694,14 @@ bool PeerManagerImpl::SendMessages(CNode* pto) LOCK(tx_relay->m_bloom_filter_mutex); for (const auto& txinfo : vtxinfo) { - const uint256& hash = peer->m_wtxid_relay ? txinfo.tx->GetWitnessHash() : txinfo.tx->GetHash(); - CInv inv(peer->m_wtxid_relay ? MSG_WTX : MSG_TX, hash); - tx_relay->m_tx_inventory_to_send.erase(hash); + CInv inv{ + peer->m_wtxid_relay ? MSG_WTX : MSG_TX, + peer->m_wtxid_relay ? + txinfo.tx->GetWitnessHash().ToUint256() : + txinfo.tx->GetHash().ToUint256(), + }; + tx_relay->m_tx_inventory_to_send.erase(inv.hash); + // Don't send transactions that peers will not put into their mempool if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) { continue; @@ -5704,7 +5709,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) if (tx_relay->m_bloom_filter) { if (!tx_relay->m_bloom_filter->IsRelevantAndUpdate(*txinfo.tx)) continue; } - tx_relay->m_tx_inventory_known_filter.insert(hash); + tx_relay->m_tx_inventory_known_filter.insert(inv.hash); vInv.push_back(inv); if (vInv.size() == MAX_INV_SZ) { m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv)); diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 2c913bf4327..1ad8345fcb4 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -65,22 +66,23 @@ std::string CTxOut::ToString() const CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime) {} -uint256 CMutableTransaction::GetHash() const +Txid CMutableTransaction::GetHash() const { - return (CHashWriter{SERIALIZE_TRANSACTION_NO_WITNESS} << *this).GetHash(); + return Txid::FromUint256((CHashWriter{SERIALIZE_TRANSACTION_NO_WITNESS} << *this).GetHash()); } -uint256 CTransaction::ComputeHash() const +Txid CTransaction::ComputeHash() const { - return (CHashWriter{SERIALIZE_TRANSACTION_NO_WITNESS} << *this).GetHash(); + return Txid::FromUint256((CHashWriter{SERIALIZE_TRANSACTION_NO_WITNESS} << *this).GetHash()); } -uint256 CTransaction::ComputeWitnessHash() const +Wtxid CTransaction::ComputeWitnessHash() const { if (!HasWitness()) { - return hash; + return Wtxid::FromUint256(hash.ToUint256()); } - return (CHashWriter{0} << *this).GetHash(); + + return Wtxid::FromUint256((CHashWriter{0} << *this).GetHash()); } CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime), hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {} diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index bd7eb16becf..2516647a840 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -11,6 +11,7 @@ #include