mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 07:39:08 +01:00
Merge bitcoin/bitcoin#28107: util: Type-safe transaction identifiers
940a49978cUse type-safe txid types in orphanage (dergoegge)ed70e65016Introduce types for txids & wtxids (dergoegge)cdb14d79e8[net processing] Use HasWitness over comparing (w)txids (dergoegge) Pull request description: We currently have two different identifiers for transactions: `txid` (refering to the hash of a transaction without witness data) and `wtxid` (referring to the hash of a transaction including witness data). Both are typed as `uint256` which could lead to type-safety bugs in which one transaction identifier type is passed where the other would be expected. This PR introduces explicit `Txid` and `Wtxid` types that (if used) would cause compilation errors for such type confusion bugs. (Only the orphanage is converted to use these types in this PR) ACKs for top commit: achow101: ACK940a49978cstickies-v: ACK940a49978chebasto: ACK940a49978c, I have reviewed the code and it looks OK. instagibbs: re-ACK940a49978cBrandonOdiwuor: re-ACK940a49978cglozow: reACK940a49978cTree-SHA512: 55298d1c2bb82b7a6995e96e554571c22eaf4a89fb2a4d7a236d70e0f625e8cca62ff2490e1c179c47bd93153fe6527b56870198f026f5ee7753d64d7a424c92
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user