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 3bfb606037c..7fcc399151d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1947,9 +1947,9 @@ void PeerManagerImpl::BlockConnected( { LOCK(m_recent_confirmed_transactions_mutex); for (const auto& ptx : pblock->vtx) { - m_recent_confirmed_transactions.insert(ptx->GetHash()); - if (ptx->GetHash() != ptx->GetWitnessHash()) { - m_recent_confirmed_transactions.insert(ptx->GetWitnessHash()); + m_recent_confirmed_transactions.insert(ptx->GetHash().ToUint256()); + if (ptx->HasWitness()) { + m_recent_confirmed_transactions.insert(ptx->GetWitnessHash().ToUint256()); } } } @@ -3003,8 +3003,8 @@ bool PeerManagerImpl::ProcessOrphanTx(Peer& peer) while (CTransactionRef porphanTx = m_orphanage.GetTxToReconsider(peer.m_id)) { const MempoolAcceptResult result = m_chainman.ProcessTransaction(porphanTx); const TxValidationState& state = result.m_state; - const uint256& orphanHash = porphanTx->GetHash(); - const uint256& orphan_wtxid = porphanTx->GetWitnessHash(); + const Txid& orphanHash = porphanTx->GetHash(); + const Wtxid& orphan_wtxid = porphanTx->GetWitnessHash(); if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) { LogPrint(BCLog::TXPACKAGES, " accepted orphan tx %s (wtxid=%s)\n", orphanHash.ToString(), orphan_wtxid.ToString()); @@ -3052,7 +3052,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 @@ -3061,10 +3061,10 @@ bool PeerManagerImpl::ProcessOrphanTx(Peer& peer) // processing of this transaction in the event that child // transactions are later received (resulting in // parent-fetching by txid via the orphan-handling logic). - if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && porphanTx->GetWitnessHash() != porphanTx->GetHash()) { + 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); @@ -4319,8 +4319,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()); } @@ -4339,7 +4339,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 @@ -4349,8 +4349,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, // processing of this transaction in the event that child // transactions are later received (resulting in // parent-fetching by txid via the orphan-handling logic). - if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash() != tx.GetHash()) { - m_recent_rejects.insert(tx.GetHash()); + if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.HasWitness()) { + m_recent_rejects.insert(tx.GetHash().ToUint256()); m_txrequest.ForgetTxHash(tx.GetHash()); } if (RecursiveDynamicUsage(*ptx) < 100000) { @@ -5780,9 +5780,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; @@ -5790,7 +5795,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