Skip to content

Commit 9efd86a

Browse files
committed
refactor: add GenTxid (=txid or wtxid) type and use it for tx request logic
1 parent d362f19 commit 9efd86a

File tree

4 files changed

+42
-17
lines changed

4 files changed

+42
-17
lines changed

src/net_processing.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ struct CNodeState {
398398
/* Track when to attempt download of announced transactions (process
399399
* time in micros -> txid)
400400
*/
401-
std::multimap<std::chrono::microseconds, uint256> m_tx_process_time;
401+
std::multimap<std::chrono::microseconds, GenTxid> m_tx_process_time;
402402

403403
//! Store all the transactions a peer has recently announced
404404
std::set<uint256> m_tx_announced;
@@ -797,23 +797,23 @@ std::chrono::microseconds CalculateTxGetDataTime(const uint256& txid, std::chron
797797
return process_time;
798798
}
799799

800-
void RequestTx(CNodeState* state, const uint256& txid, std::chrono::microseconds current_time) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
800+
void RequestTx(CNodeState* state, const GenTxid& gtxid, std::chrono::microseconds current_time) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
801801
{
802802
CNodeState::TxDownloadState& peer_download_state = state->m_tx_download;
803803
if (peer_download_state.m_tx_announced.size() >= MAX_PEER_TX_ANNOUNCEMENTS ||
804804
peer_download_state.m_tx_process_time.size() >= MAX_PEER_TX_ANNOUNCEMENTS ||
805-
peer_download_state.m_tx_announced.count(txid)) {
805+
peer_download_state.m_tx_announced.count(gtxid.GetHash())) {
806806
// Too many queued announcements from this peer, or we already have
807807
// this announcement
808808
return;
809809
}
810-
peer_download_state.m_tx_announced.insert(txid);
810+
peer_download_state.m_tx_announced.insert(gtxid.GetHash());
811811

812812
// Calculate the time to try requesting this transaction. Use
813813
// fPreferredDownload as a proxy for outbound peers.
814-
const auto process_time = CalculateTxGetDataTime(txid, current_time, !state->fPreferredDownload, !state->m_wtxid_relay && g_wtxid_relay_peers > 0);
814+
const auto process_time = CalculateTxGetDataTime(gtxid.GetHash(), current_time, !state->fPreferredDownload, !state->m_wtxid_relay && g_wtxid_relay_peers > 0);
815815

816-
peer_download_state.m_tx_process_time.emplace(process_time, txid);
816+
peer_download_state.m_tx_process_time.emplace(process_time, gtxid);
817817
}
818818

819819
} // namespace
@@ -2678,7 +2678,7 @@ void ProcessMessage(
26782678
pfrom.fDisconnect = true;
26792679
return;
26802680
} else if (!fAlreadyHave && !chainman.ActiveChainstate().IsInitialBlockDownload()) {
2681-
RequestTx(State(pfrom.GetId()), inv.hash, current_time);
2681+
RequestTx(State(pfrom.GetId()), ToGenTxid(inv), current_time);
26822682
}
26832683
}
26842684
}
@@ -2994,7 +2994,7 @@ void ProcessMessage(
29942994
// protocol for getting all unconfirmed parents.
29952995
CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash);
29962996
pfrom.AddKnownTx(txin.prevout.hash);
2997-
if (!AlreadyHave(_inv, mempool)) RequestTx(State(pfrom.GetId()), _inv.hash, current_time);
2997+
if (!AlreadyHave(_inv, mempool)) RequestTx(State(pfrom.GetId()), ToGenTxid(_inv), current_time);
29982998
}
29992999
}
30003000
AddOrphanTx(ptx, pfrom.GetId());
@@ -4529,24 +4529,24 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
45294529

45304530
auto& tx_process_time = state.m_tx_download.m_tx_process_time;
45314531
while (!tx_process_time.empty() && tx_process_time.begin()->first <= current_time && state.m_tx_download.m_tx_in_flight.size() < MAX_PEER_TX_IN_FLIGHT) {
4532-
const uint256 txid = tx_process_time.begin()->second;
4532+
const GenTxid gtxid = tx_process_time.begin()->second;
45334533
// Erase this entry from tx_process_time (it may be added back for
45344534
// processing at a later time, see below)
45354535
tx_process_time.erase(tx_process_time.begin());
4536-
CInv inv(state.m_wtxid_relay ? MSG_WTX : (MSG_TX | GetFetchFlags(*pto)), txid);
4536+
CInv inv(gtxid.IsWtxid() ? MSG_WTX : (MSG_TX | GetFetchFlags(*pto)), gtxid.GetHash());
45374537
if (!AlreadyHave(inv, m_mempool)) {
45384538
// If this transaction was last requested more than 1 minute ago,
45394539
// then request.
4540-
const auto last_request_time = GetTxRequestTime(inv.hash);
4540+
const auto last_request_time = GetTxRequestTime(gtxid.GetHash());
45414541
if (last_request_time <= current_time - GETDATA_TX_INTERVAL) {
45424542
LogPrint(BCLog::NET, "Requesting %s peer=%d\n", inv.ToString(), pto->GetId());
45434543
vGetData.push_back(inv);
45444544
if (vGetData.size() >= MAX_GETDATA_SZ) {
45454545
connman->PushMessage(pto, msgMaker.Make(NetMsgType::GETDATA, vGetData));
45464546
vGetData.clear();
45474547
}
4548-
UpdateTxRequestTime(inv.hash, current_time);
4549-
state.m_tx_download.m_tx_in_flight.emplace(inv.hash, current_time);
4548+
UpdateTxRequestTime(gtxid.GetHash(), current_time);
4549+
state.m_tx_download.m_tx_in_flight.emplace(gtxid.GetHash(), current_time);
45504550
} else {
45514551
// This transaction is in flight from someone else; queue
45524552
// up processing to happen after the download times out
@@ -4560,13 +4560,13 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
45604560
// would open us up to an attacker using inbound
45614561
// wtxid-relay to prevent us from requesting transactions
45624562
// from outbound txid-relay peers).
4563-
const auto next_process_time = CalculateTxGetDataTime(txid, current_time, !state.fPreferredDownload, false);
4564-
tx_process_time.emplace(next_process_time, txid);
4563+
const auto next_process_time = CalculateTxGetDataTime(gtxid.GetHash(), current_time, !state.fPreferredDownload, false);
4564+
tx_process_time.emplace(next_process_time, gtxid);
45654565
}
45664566
} else {
45674567
// We have already seen this transaction, no need to download.
4568-
state.m_tx_download.m_tx_announced.erase(inv.hash);
4569-
state.m_tx_download.m_tx_in_flight.erase(inv.hash);
4568+
state.m_tx_download.m_tx_announced.erase(gtxid.GetHash());
4569+
state.m_tx_download.m_tx_in_flight.erase(gtxid.GetHash());
45704570
}
45714571
}
45724572

src/primitives/transaction.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <serialize.h>
1313
#include <uint256.h>
1414

15+
#include <tuple>
16+
1517
static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;
1618

1719
/** An outpoint - a combination of a transaction hash and an index n into its vout */
@@ -388,4 +390,17 @@ typedef std::shared_ptr<const CTransaction> CTransactionRef;
388390
static inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); }
389391
template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
390392

393+
/** A generic txid reference (txid or wtxid). */
394+
class GenTxid
395+
{
396+
const bool m_is_wtxid;
397+
const uint256 m_hash;
398+
public:
399+
GenTxid(bool is_wtxid, const uint256& hash) : m_is_wtxid(is_wtxid), m_hash(hash) {}
400+
bool IsWtxid() const { return m_is_wtxid; }
401+
const uint256& GetHash() const { return m_hash; }
402+
friend bool operator==(const GenTxid& a, const GenTxid& b) { return a.m_is_wtxid == b.m_is_wtxid && a.m_hash == b.m_hash; }
403+
friend bool operator<(const GenTxid& a, const GenTxid& b) { return std::tie(a.m_is_wtxid, a.m_hash) < std::tie(b.m_is_wtxid, b.m_hash); }
404+
};
405+
391406
#endif // BITCOIN_PRIMITIVES_TRANSACTION_H

src/protocol.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,9 @@ std::vector<std::string> serviceFlagsToStr(uint64_t flags)
241241

242242
return str_flags;
243243
}
244+
245+
GenTxid ToGenTxid(const CInv& inv)
246+
{
247+
assert(inv.IsGenTxMsg());
248+
return {inv.IsMsgWtx(), inv.hash};
249+
}

src/protocol.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#define BITCOIN_PROTOCOL_H
1212

1313
#include <netaddress.h>
14+
#include <primitives/transaction.h>
1415
#include <serialize.h>
1516
#include <uint256.h>
1617
#include <version.h>
@@ -442,4 +443,7 @@ class CInv
442443
uint256 hash;
443444
};
444445

446+
/** Convert a TX/WITNESS_TX/WTX CInv to a GenTxid. */
447+
GenTxid ToGenTxid(const CInv& inv);
448+
445449
#endif // BITCOIN_PROTOCOL_H

0 commit comments

Comments
 (0)