Skip to content

Commit 23e15d4

Browse files
committed
Merge bitcoin/bitcoin#32631: refactor: Convert GenTxid to std::variant
a60f863 scripted-diff: Replace GenTxidVariant with GenTxid (marcofleon) c8ba199 Remove old GenTxid class (marcofleon) 072a198 Convert remaining instances of GenTxid to GenTxidVariant (marcofleon) 1b52839 Convert `txrequest` to GenTxidVariant (marcofleon) bde4579 Convert `txdownloadman_impl` to GenTxidVariant (marcofleon) c876a89 Replace GenTxid with Txid/Wtxid overloads in `txmempool` (marcofleon) de858ce move-only: make GetInfo a private CTxMemPool member (stickies-v) eee473d Convert `CompareInvMempoolOrder` to GenTxidVariant (marcofleon) 243553d refactor: replace get_iter_from_wtxid with GetIter(const Wtxid&) (stickies-v) fcf92fd refactor: make CTxMemPool::GetIter strongly typed (marcofleon) 11d28f2 Implement GenTxid as a variant (marcofleon) Pull request description: Part of the [type safety refactor](bitcoin/bitcoin#32189). This PR changes the GenTxid class to a variant, which holds both Txids and Wtxids. This provides compile-time type safety and eliminates the manual type check (bool m_is_wtxid). Variables that can be either a Txid or a Wtxid are now using the new GenTxid variant, instead of uint256. ACKs for top commit: w0xlt: ACK bitcoin/bitcoin@a60f863 dergoegge: Code review ACK a60f863 maflcko: review ACK a60f863 🎽 theStack: Code-review ACK a60f863 Tree-SHA512: da9b73b7bdffee2eb9281a409205519ac330d3336094d17681896703fbca8099608782c9c85801e388e4d90af5af8abf1f34931f57bbbe6e9674d802d6066047
2 parents 8ffbd7b + a60f863 commit 23e15d4

33 files changed

+313
-316
lines changed

src/interfaces/chain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ class Chain
208208
virtual RBFTransactionState isRBFOptIn(const CTransaction& tx) = 0;
209209

210210
//! Check if transaction is in mempool.
211-
virtual bool isInMempool(const uint256& txid) = 0;
211+
virtual bool isInMempool(const Txid& txid) = 0;
212212

213213
//! Check if transaction has descendants in mempool.
214214
virtual bool hasDescendantsInMempool(const uint256& txid) = 0;

src/net_processing.cpp

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ struct Peer {
302302
* non-wtxid-relay peers, wtxid for wtxid-relay peers). We use the
303303
* mempool to sort transactions in dependency order before relay, so
304304
* this does not have to be sorted. */
305-
std::set<uint256> m_tx_inventory_to_send GUARDED_BY(m_tx_inventory_mutex);
305+
std::set<GenTxid> m_tx_inventory_to_send GUARDED_BY(m_tx_inventory_mutex);
306306
/** Whether the peer has requested us to send our complete mempool. Only
307307
* permitted if the peer has NetPermissionFlags::Mempool or we advertise
308308
* NODE_BLOOM. See BIP35. */
@@ -536,7 +536,7 @@ class PeerManagerImpl final : public PeerManager
536536
std::vector<TxOrphanage::OrphanTxBase> GetOrphanTransactions() override EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
537537
PeerManagerInfo GetInfo() const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
538538
void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
539-
void RelayTransaction(const uint256& txid, const uint256& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
539+
void RelayTransaction(const Txid& txid, const Wtxid& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
540540
void SetBestBlock(int height, std::chrono::seconds time) override
541541
{
542542
m_best_height = height;
@@ -856,7 +856,7 @@ class PeerManagerImpl final : public PeerManager
856856
std::shared_ptr<const CBlock> m_most_recent_block GUARDED_BY(m_most_recent_block_mutex);
857857
std::shared_ptr<const CBlockHeaderAndShortTxIDs> m_most_recent_compact_block GUARDED_BY(m_most_recent_block_mutex);
858858
uint256 m_most_recent_block_hash GUARDED_BY(m_most_recent_block_mutex);
859-
std::unique_ptr<const std::map<uint256, CTransactionRef>> m_most_recent_block_txs GUARDED_BY(m_most_recent_block_mutex);
859+
std::unique_ptr<const std::map<GenTxid, CTransactionRef>> m_most_recent_block_txs GUARDED_BY(m_most_recent_block_mutex);
860860

861861
// Data about the low-work headers synchronization, aggregated from all peers' HeadersSyncStates.
862862
/** Mutex guarding the other m_headers_presync_* variables. */
@@ -947,7 +947,7 @@ class PeerManagerImpl final : public PeerManager
947947
std::atomic<std::chrono::seconds> m_last_tip_update{0s};
948948

949949
/** Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed). */
950-
CTransactionRef FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid)
950+
CTransactionRef FindTxForGetData(const Peer::TxRelay& tx_relay, const CInv& inv)
951951
EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, NetEventsInterface::g_msgproc_mutex);
952952

953953
void ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic<bool>& interruptMsgProc)
@@ -1583,7 +1583,7 @@ void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler& scheduler)
15831583
CTransactionRef tx = m_mempool.get(txid);
15841584

15851585
if (tx != nullptr) {
1586-
RelayTransaction(txid, tx->GetWitnessHash());
1586+
RelayTransaction(Txid::FromUint256(txid), tx->GetWitnessHash());
15871587
} else {
15881588
m_mempool.RemoveUnbroadcastTx(txid, true);
15891589
}
@@ -2027,7 +2027,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
20272027
std::async(std::launch::deferred, [&] { return NetMsg::Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })};
20282028

20292029
{
2030-
auto most_recent_block_txs = std::make_unique<std::map<uint256, CTransactionRef>>();
2030+
auto most_recent_block_txs = std::make_unique<std::map<GenTxid, CTransactionRef>>();
20312031
for (const auto& tx : pblock->vtx) {
20322032
most_recent_block_txs->emplace(tx->GetHash(), tx);
20332033
most_recent_block_txs->emplace(tx->GetWitnessHash(), tx);
@@ -2150,7 +2150,7 @@ void PeerManagerImpl::SendPings()
21502150
for(auto& it : m_peer_map) it.second->m_ping_queued = true;
21512151
}
21522152

2153-
void PeerManagerImpl::RelayTransaction(const uint256& txid, const uint256& wtxid)
2153+
void PeerManagerImpl::RelayTransaction(const Txid& txid, const Wtxid& wtxid)
21542154
{
21552155
LOCK(m_peer_mutex);
21562156
for(auto& it : m_peer_map) {
@@ -2166,11 +2166,11 @@ void PeerManagerImpl::RelayTransaction(const uint256& txid, const uint256& wtxid
21662166
// in the announcement.
21672167
if (tx_relay->m_next_inv_send_time == 0s) continue;
21682168

2169-
const uint256& hash{peer.m_wtxid_relay ? wtxid : txid};
2170-
if (!tx_relay->m_tx_inventory_known_filter.contains(hash)) {
2171-
tx_relay->m_tx_inventory_to_send.insert(hash);
2169+
const auto gtxid{peer.m_wtxid_relay ? GenTxid{wtxid} : GenTxid{txid}};
2170+
if (!tx_relay->m_tx_inventory_known_filter.contains(gtxid.ToUint256())) {
2171+
tx_relay->m_tx_inventory_to_send.insert(gtxid);
21722172
}
2173-
};
2173+
}
21742174
}
21752175

21762176
void PeerManagerImpl::RelayAddress(NodeId originator,
@@ -2391,10 +2391,15 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
23912391
}
23922392
}
23932393

2394-
CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid)
2394+
CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay, const CInv& inv)
23952395
{
2396+
auto gtxid{ToGenTxid(inv)};
23962397
// If a tx was in the mempool prior to the last INV for this peer, permit the request.
2397-
auto txinfo = m_mempool.info_for_relay(gtxid, tx_relay.m_last_inv_sequence);
2398+
auto txinfo{std::visit(
2399+
[&](const auto& id) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex) {
2400+
return m_mempool.info_for_relay(id, tx_relay.m_last_inv_sequence);
2401+
},
2402+
gtxid)};
23982403
if (txinfo.tx) {
23992404
return std::move(txinfo.tx);
24002405
}
@@ -2403,7 +2408,7 @@ CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay,
24032408
{
24042409
LOCK(m_most_recent_block_mutex);
24052410
if (m_most_recent_block_txs != nullptr) {
2406-
auto it = m_most_recent_block_txs->find(gtxid.GetHash());
2411+
auto it = m_most_recent_block_txs->find(gtxid);
24072412
if (it != m_most_recent_block_txs->end()) return it->second;
24082413
}
24092414
}
@@ -2437,8 +2442,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
24372442
continue;
24382443
}
24392444

2440-
CTransactionRef tx = FindTxForGetData(*tx_relay, ToGenTxid(inv));
2441-
if (tx) {
2445+
if (auto tx{FindTxForGetData(*tx_relay, inv)}) {
24422446
// WTX and WITNESS_TX imply we serialize with witness
24432447
const auto maybe_with_witness = (inv.IsMsgTx() ? TX_NO_WITNESS : TX_WITH_WITNESS);
24442448
MakeAndPushMessage(pfrom, NetMsgType::TX, maybe_with_witness(*tx));
@@ -4294,7 +4298,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
42944298
// Always relay transactions received from peers with forcerelay
42954299
// permission, even if they were already in the mempool, allowing
42964300
// the node to function as a gateway for nodes hidden behind it.
4297-
if (!m_mempool.exists(GenTxid::Txid(tx.GetHash()))) {
4301+
if (!m_mempool.exists(tx.GetHash())) {
42984302
LogPrintf("Not relaying non-mempool transaction %s (wtxid=%s) from forcerelay peer=%d\n",
42994303
tx.GetHash().ToString(), tx.GetWitnessHash().ToString(), pfrom.GetId());
43004304
} else {
@@ -4928,11 +4932,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
49284932
if (msg_type == NetMsgType::NOTFOUND) {
49294933
std::vector<CInv> vInv;
49304934
vRecv >> vInv;
4931-
std::vector<uint256> tx_invs;
4935+
std::vector<GenTxid> tx_invs;
49324936
if (vInv.size() <= node::MAX_PEER_TX_ANNOUNCEMENTS + MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
49334937
for (CInv &inv : vInv) {
49344938
if (inv.IsGenTxMsg()) {
4935-
tx_invs.emplace_back(inv.hash);
4939+
tx_invs.emplace_back(ToGenTxid(inv));
49364940
}
49374941
}
49384942
}
@@ -5432,20 +5436,15 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
54325436
namespace {
54335437
class CompareInvMempoolOrder
54345438
{
5435-
CTxMemPool* mp;
5436-
bool m_wtxid_relay;
5439+
const CTxMemPool* m_mempool;
54375440
public:
5438-
explicit CompareInvMempoolOrder(CTxMemPool *_mempool, bool use_wtxid)
5439-
{
5440-
mp = _mempool;
5441-
m_wtxid_relay = use_wtxid;
5442-
}
5441+
explicit CompareInvMempoolOrder(CTxMemPool* mempool) : m_mempool{mempool} {}
54435442

5444-
bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
5443+
bool operator()(std::set<GenTxid>::iterator a, std::set<GenTxid>::iterator b)
54455444
{
54465445
/* As std::make_heap produces a max-heap, we want the entries with the
54475446
* fewest ancestors/highest fee to sort later. */
5448-
return mp->CompareDepthAndScore(*b, *a, m_wtxid_relay);
5447+
return m_mempool->CompareDepthAndScore(*b, *a);
54495448
}
54505449
};
54515450
} // namespace
@@ -5763,7 +5762,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
57635762
txinfo.tx->GetWitnessHash().ToUint256() :
57645763
txinfo.tx->GetHash().ToUint256(),
57655764
};
5766-
tx_relay->m_tx_inventory_to_send.erase(inv.hash);
5765+
tx_relay->m_tx_inventory_to_send.erase(ToGenTxid(inv));
57675766

57685767
// Don't send transactions that peers will not put into their mempool
57695768
if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
@@ -5784,15 +5783,15 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
57845783
// Determine transactions to relay
57855784
if (fSendTrickle) {
57865785
// Produce a vector with all candidates for sending
5787-
std::vector<std::set<uint256>::iterator> vInvTx;
5786+
std::vector<std::set<GenTxid>::iterator> vInvTx;
57885787
vInvTx.reserve(tx_relay->m_tx_inventory_to_send.size());
5789-
for (std::set<uint256>::iterator it = tx_relay->m_tx_inventory_to_send.begin(); it != tx_relay->m_tx_inventory_to_send.end(); it++) {
5788+
for (std::set<GenTxid>::iterator it = tx_relay->m_tx_inventory_to_send.begin(); it != tx_relay->m_tx_inventory_to_send.end(); it++) {
57905789
vInvTx.push_back(it);
57915790
}
57925791
const CFeeRate filterrate{tx_relay->m_fee_filter_received.load()};
57935792
// Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
57945793
// A heap is used so that not all items need sorting if only a few are being sent.
5795-
CompareInvMempoolOrder compareInvMempoolOrder(&m_mempool, peer->m_wtxid_relay);
5794+
CompareInvMempoolOrder compareInvMempoolOrder(&m_mempool);
57965795
std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
57975796
// No reason to drain out at many times the network's capacity,
57985797
// especially since we have many peers and some will draw much shorter delays.
@@ -5803,18 +5802,19 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
58035802
while (!vInvTx.empty() && nRelayedTransactions < broadcast_max) {
58045803
// Fetch the top element from the heap
58055804
std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
5806-
std::set<uint256>::iterator it = vInvTx.back();
5805+
std::set<GenTxid>::iterator it = vInvTx.back();
58075806
vInvTx.pop_back();
5808-
uint256 hash = *it;
5809-
CInv inv(peer->m_wtxid_relay ? MSG_WTX : MSG_TX, hash);
5807+
GenTxid hash = *it;
5808+
Assume(peer->m_wtxid_relay == hash.IsWtxid());
5809+
CInv inv(peer->m_wtxid_relay ? MSG_WTX : MSG_TX, hash.ToUint256());
58105810
// Remove it from the to-be-sent set
58115811
tx_relay->m_tx_inventory_to_send.erase(it);
58125812
// Check if not in the filter already
5813-
if (tx_relay->m_tx_inventory_known_filter.contains(hash)) {
5813+
if (tx_relay->m_tx_inventory_known_filter.contains(hash.ToUint256())) {
58145814
continue;
58155815
}
58165816
// Not in the mempool anymore? don't bother sending it.
5817-
auto txinfo = m_mempool.info(ToGenTxid(inv));
5817+
auto txinfo{std::visit([&](const auto& id) { return m_mempool.info(id); }, hash)};
58185818
if (!txinfo.tx) {
58195819
continue;
58205820
}
@@ -5830,7 +5830,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
58305830
MakeAndPushMessage(*pto, NetMsgType::INV, vInv);
58315831
vInv.clear();
58325832
}
5833-
tx_relay->m_tx_inventory_known_filter.insert(hash);
5833+
tx_relay->m_tx_inventory_known_filter.insert(hash.ToUint256());
58345834
}
58355835

58365836
// Ensure we'll respond to GETDATA requests for anything we've just announced
@@ -5953,7 +5953,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
59535953
{
59545954
LOCK(m_tx_download_mutex);
59555955
for (const GenTxid& gtxid : m_txdownloadman.GetRequestsToSend(pto->GetId(), current_time)) {
5956-
vGetData.emplace_back(gtxid.IsWtxid() ? MSG_WTX : (MSG_TX | GetFetchFlags(*peer)), gtxid.GetHash());
5956+
vGetData.emplace_back(gtxid.IsWtxid() ? MSG_WTX : (MSG_TX | GetFetchFlags(*peer)), gtxid.ToUint256());
59575957
if (vGetData.size() >= MAX_GETDATA_SZ) {
59585958
MakeAndPushMessage(*pto, NetMsgType::GETDATA, vGetData);
59595959
vGetData.clear();

src/net_processing.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class PeerManager : public CValidationInterface, public NetEventsInterface
119119
virtual PeerManagerInfo GetInfo() const = 0;
120120

121121
/** Relay transaction to all peers. */
122-
virtual void RelayTransaction(const uint256& txid, const uint256& wtxid) = 0;
122+
virtual void RelayTransaction(const Txid& txid, const Wtxid& wtxid) = 0;
123123

124124
/** Send ping message to all peers */
125125
virtual void SendPings() = 0;

src/node/interfaces.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,11 @@ class ChainImpl : public Chain
667667
LOCK(m_node.mempool->cs);
668668
return IsRBFOptIn(tx, *m_node.mempool);
669669
}
670-
bool isInMempool(const uint256& txid) override
670+
bool isInMempool(const Txid& txid) override
671671
{
672672
if (!m_node.mempool) return false;
673673
LOCK(m_node.mempool->cs);
674-
return m_node.mempool->exists(GenTxid::Txid(txid));
674+
return m_node.mempool->exists(txid);
675675
}
676676
bool hasDescendantsInMempool(const uint256& txid) override
677677
{

src/node/mempool_persist.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, Chainstate& active
107107
// wallet(s) having loaded it while we were processing
108108
// mempool transactions; consider these as valid, instead of
109109
// failed, but mark them as 'already there'
110-
if (pool.exists(GenTxid::Txid(tx->GetHash()))) {
110+
if (pool.exists(tx->GetHash())) {
111111
++already_there;
112112
} else {
113113
++failed;

src/node/mini_miner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ MiniMiner::MiniMiner(const CTxMemPool& mempool, const std::vector<COutPoint>& ou
2727
// Anything that's spent by the mempool is to-be-replaced
2828
// Anything otherwise unavailable just has a bump fee of 0
2929
for (const auto& outpoint : outpoints) {
30-
if (!mempool.exists(GenTxid::Txid(outpoint.hash))) {
30+
if (!mempool.exists(outpoint.hash)) {
3131
// This UTXO is either confirmed or not yet submitted to mempool.
3232
// If it's confirmed, no bump fee is required.
3333
// If it's not yet submitted, we have no information, so return 0.

src/node/transaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
4242

4343
std::promise<void> promise;
4444
Txid txid = tx->GetHash();
45-
uint256 wtxid = tx->GetWitnessHash();
45+
Wtxid wtxid = tx->GetWitnessHash();
4646
bool callback_set = false;
4747

4848
{

src/node/txdownloadman.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <net.h>
99
#include <policy/packages.h>
1010
#include <txorphanage.h>
11+
#include <util/transaction_identifier.h>
1112

1213
#include <cstdint>
1314
#include <memory>
@@ -143,7 +144,7 @@ class TxDownloadManager {
143144
std::vector<GenTxid> GetRequestsToSend(NodeId nodeid, std::chrono::microseconds current_time);
144145

145146
/** Should be called when a notfound for a tx has been received. */
146-
void ReceivedNotFound(NodeId nodeid, const std::vector<uint256>& txhashes);
147+
void ReceivedNotFound(NodeId nodeid, const std::vector<GenTxid>& gtxids);
147148

148149
/** Respond to successful transaction submission to mempool */
149150
void MempoolAcceptedTx(const CTransactionRef& tx);

0 commit comments

Comments
 (0)