Skip to content

Commit f7c73b0

Browse files
committed
Merge #19569: Enable fetching of orphan parents from wtxid peers
10b7a6d refactor: make txmempool interface use GenTxid (Pieter Wuille) 5c124e1 refactor: make FindTxForGetData use GenTxid (Pieter Wuille) a2bfac8 refactor: use GenTxid in tx request functions (Pieter Wuille) e65d115 test: request parents of orphan from wtxid relay peer (Anthony Towns) 900d7f6 p2p: enable fetching of orphans from wtxid peers (Pieter Wuille) 9efd86a refactor: add GenTxid (=txid or wtxid) type and use it for tx request logic (Pieter Wuille) d362f19 doc: list support for BIP 339 in doc/bips.md (Pieter Wuille) Pull request description: This is based on bitcoin/bitcoin#18044 (comment). A new type `GenTxid` is added to protocol.h, which represents a tagged txid-or-wtxid. The tx request logic is updated to use these instead of uint256s, permitting per-announcement distinguishing of txid/wtxid (instead of assuming that everything we want to request from a wtxid peer is wtx). Then the restriction of orphan-parent requesting to non-wtxid peers is lifted. Also document BIP339 in doc/bips.md. ACKs for top commit: jnewbery: Code review ACK 10b7a6d jonatack: ACK 10b7a6d ajtowns: ACK 10b7a6d -- code review. Using gtxid to replace the is_txid_or_wtxid flag for the mempool functions is nice. naumenkogs: utACK 10b7a6d Tree-SHA512: d518d13ffd71f8d2b3c175dc905362a7259689e6022a97a0b4f14f1f9fdd87475cf5af70cb12338d1e5d31b52c12e4faaea436114056a2ae9669cb506240758b
2 parents a63a26f + 10b7a6d commit f7c73b0

File tree

8 files changed

+96
-63
lines changed

8 files changed

+96
-63
lines changed

doc/bips.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.19.0**):
1+
BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.21.0**):
22

33
* [`BIP 9`](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki): The changes allowing multiple soft-forks to be deployed in parallel have been implemented since **v0.12.1** ([PR #7575](https://github.com/bitcoin/bitcoin/pull/7575))
44
* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
@@ -42,3 +42,4 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.19.0**):
4242
* [`BIP 173`](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki): Bech32 addresses for native Segregated Witness outputs are supported as of **v0.16.0** ([PR 11167](https://github.com/bitcoin/bitcoin/pull/11167)). Bech32 addresses are generated by default as of **v0.20.0** ([PR 16884](https://github.com/bitcoin/bitcoin/pull/16884)).
4343
* [`BIP 174`](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki): RPCs to operate on Partially Signed Bitcoin Transactions (PSBT) are present as of **v0.17.0** ([PR 13557](https://github.com/bitcoin/bitcoin/pull/13557)).
4444
* [`BIP 176`](https://github.com/bitcoin/bips/blob/master/bip-0176.mediawiki): Bits Denomination [QT only] is supported as of **v0.16.0** ([PR 12035](https://github.com/bitcoin/bitcoin/pull/12035)).
45+
* [`BIP 339`](https://github.com/bitcoin/bips/blob/master/bip-0339.mediawiki): Relay of transactions by wtxid is supported as of **v0.21.0** ([PR 18044](https://github.com/bitcoin/bitcoin/pull/18044)).

src/net_processing.cpp

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ namespace {
236236
/** When our tip was last updated. */
237237
std::atomic<int64_t> g_last_tip_update(0);
238238

239-
/** Relay map */
239+
/** Relay map (txid or wtxid -> CTransactionRef) */
240240
typedef std::map<uint256, CTransactionRef> MapRelay;
241241
MapRelay mapRelay GUARDED_BY(cs_main);
242242
/** Expiration-time ordered list of (expire time, relay map entry) pairs. */
@@ -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;
@@ -751,34 +751,34 @@ static void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vec
751751
}
752752
}
753753

754-
void EraseTxRequest(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
754+
void EraseTxRequest(const GenTxid& gtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
755755
{
756-
g_already_asked_for.erase(txid);
756+
g_already_asked_for.erase(gtxid.GetHash());
757757
}
758758

759-
std::chrono::microseconds GetTxRequestTime(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
759+
std::chrono::microseconds GetTxRequestTime(const GenTxid& gtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
760760
{
761-
auto it = g_already_asked_for.find(txid);
761+
auto it = g_already_asked_for.find(gtxid.GetHash());
762762
if (it != g_already_asked_for.end()) {
763763
return it->second;
764764
}
765765
return {};
766766
}
767767

768-
void UpdateTxRequestTime(const uint256& txid, std::chrono::microseconds request_time) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
768+
void UpdateTxRequestTime(const GenTxid& gtxid, std::chrono::microseconds request_time) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
769769
{
770-
auto it = g_already_asked_for.find(txid);
770+
auto it = g_already_asked_for.find(gtxid.GetHash());
771771
if (it == g_already_asked_for.end()) {
772-
g_already_asked_for.insert(std::make_pair(txid, request_time));
772+
g_already_asked_for.insert(std::make_pair(gtxid.GetHash(), request_time));
773773
} else {
774774
g_already_asked_for.update(it, request_time);
775775
}
776776
}
777777

778-
std::chrono::microseconds CalculateTxGetDataTime(const uint256& txid, std::chrono::microseconds current_time, bool use_inbound_delay, bool use_txid_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
778+
std::chrono::microseconds CalculateTxGetDataTime(const GenTxid& gtxid, std::chrono::microseconds current_time, bool use_inbound_delay, bool use_txid_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
779779
{
780780
std::chrono::microseconds process_time;
781-
const auto last_request_time = GetTxRequestTime(txid);
781+
const auto last_request_time = GetTxRequestTime(gtxid);
782782
// First time requesting this tx
783783
if (last_request_time.count() == 0) {
784784
process_time = current_time;
@@ -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, 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
@@ -1453,7 +1453,7 @@ bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool) EXCLUSIVE_LO
14531453
if (g_recent_confirmed_transactions->contains(inv.hash)) return true;
14541454
}
14551455

1456-
return recentRejects->contains(inv.hash) || mempool.exists(inv.hash, inv.IsMsgWtx());
1456+
return recentRejects->contains(inv.hash) || mempool.exists(ToGenTxid(inv));
14571457
}
14581458
case MSG_BLOCK:
14591459
case MSG_WITNESS_BLOCK:
@@ -1671,9 +1671,9 @@ void static ProcessGetBlockData(CNode& pfrom, const CChainParams& chainparams, c
16711671
}
16721672

16731673
//! Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed).
1674-
CTransactionRef static FindTxForGetData(const CNode& peer, const uint256& txid_or_wtxid, bool use_wtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) LOCKS_EXCLUDED(cs_main)
1674+
CTransactionRef static FindTxForGetData(const CNode& peer, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) LOCKS_EXCLUDED(cs_main)
16751675
{
1676-
auto txinfo = mempool.info(txid_or_wtxid, use_wtxid);
1676+
auto txinfo = mempool.info(gtxid);
16771677
if (txinfo.tx) {
16781678
// If a TX could have been INVed in reply to a MEMPOOL request,
16791679
// or is older than UNCONDITIONAL_RELAY_DELAY, permit the request
@@ -1686,11 +1686,11 @@ CTransactionRef static FindTxForGetData(const CNode& peer, const uint256& txid_o
16861686
{
16871687
LOCK(cs_main);
16881688
// Otherwise, the transaction must have been announced recently.
1689-
if (State(peer.GetId())->m_recently_announced_invs.contains(txid_or_wtxid)) {
1689+
if (State(peer.GetId())->m_recently_announced_invs.contains(gtxid.GetHash())) {
16901690
// If it was, it can be relayed from either the mempool...
16911691
if (txinfo.tx) return std::move(txinfo.tx);
16921692
// ... or the relay pool.
1693-
auto mi = mapRelay.find(txid_or_wtxid);
1693+
auto mi = mapRelay.find(gtxid.GetHash());
16941694
if (mi != mapRelay.end()) return mi->second;
16951695
}
16961696
}
@@ -1727,7 +1727,7 @@ void static ProcessGetData(CNode& pfrom, const CChainParams& chainparams, CConnm
17271727
continue;
17281728
}
17291729

1730-
CTransactionRef tx = FindTxForGetData(pfrom, inv.hash, inv.IsMsgWtx(), mempool_req, now);
1730+
CTransactionRef tx = FindTxForGetData(pfrom, ToGenTxid(inv), mempool_req, now);
17311731
if (tx) {
17321732
// WTX and WITNESS_TX imply we serialize with witness
17331733
int nSendFlags = (inv.IsMsgTx() ? SERIALIZE_TRANSACTION_NO_WITNESS : 0);
@@ -2647,7 +2647,9 @@ void ProcessMessage(
26472647
if (interruptMsgProc)
26482648
return;
26492649

2650-
// ignore INVs that don't match wtxidrelay setting
2650+
// Ignore INVs that don't match wtxidrelay setting.
2651+
// Note that orphan parent fetching always uses MSG_TX GETDATAs regardless of the wtxidrelay setting.
2652+
// This is fine as no INV messages are involved in that process.
26512653
if (State(pfrom.GetId())->m_wtxid_relay) {
26522654
if (inv.IsMsgTx()) continue;
26532655
} else {
@@ -2678,7 +2680,7 @@ void ProcessMessage(
26782680
pfrom.fDisconnect = true;
26792681
return;
26802682
} else if (!fAlreadyHave && !chainman.ActiveChainstate().IsInitialBlockDownload()) {
2681-
RequestTx(State(pfrom.GetId()), inv.hash, current_time);
2683+
RequestTx(State(pfrom.GetId()), ToGenTxid(inv), current_time);
26822684
}
26832685
}
26842686
}
@@ -2931,9 +2933,11 @@ void ProcessMessage(
29312933

29322934
TxValidationState state;
29332935

2934-
nodestate->m_tx_download.m_tx_announced.erase(hash);
2935-
nodestate->m_tx_download.m_tx_in_flight.erase(hash);
2936-
EraseTxRequest(hash);
2936+
for (const GenTxid& gtxid : {GenTxid(false, txid), GenTxid(true, wtxid)}) {
2937+
nodestate->m_tx_download.m_tx_announced.erase(gtxid.GetHash());
2938+
nodestate->m_tx_download.m_tx_in_flight.erase(gtxid.GetHash());
2939+
EraseTxRequest(gtxid);
2940+
}
29372941

29382942
std::list<CTransactionRef> lRemovedTxn;
29392943

@@ -2985,17 +2989,15 @@ void ProcessMessage(
29852989
uint32_t nFetchFlags = GetFetchFlags(pfrom);
29862990
const auto current_time = GetTime<std::chrono::microseconds>();
29872991

2988-
if (!State(pfrom.GetId())->m_wtxid_relay) {
2989-
for (const CTxIn& txin : tx.vin) {
2990-
// Here, we only have the txid (and not wtxid) of the
2991-
// inputs, so we only request parents from
2992-
// non-wtxid-relay peers.
2993-
// Eventually we should replace this with an improved
2994-
// protocol for getting all unconfirmed parents.
2995-
CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash);
2996-
pfrom.AddKnownTx(txin.prevout.hash);
2997-
if (!AlreadyHave(_inv, mempool)) RequestTx(State(pfrom.GetId()), _inv.hash, current_time);
2998-
}
2992+
for (const CTxIn& txin : tx.vin) {
2993+
// Here, we only have the txid (and not wtxid) of the
2994+
// inputs, so we only request in txid mode, even for
2995+
// wtxidrelay peers.
2996+
// Eventually we should replace this with an improved
2997+
// protocol for getting all unconfirmed parents.
2998+
CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash);
2999+
pfrom.AddKnownTx(txin.prevout.hash);
3000+
if (!AlreadyHave(_inv, mempool)) RequestTx(State(pfrom.GetId()), ToGenTxid(_inv), current_time);
29993001
}
30003002
AddOrphanTx(ptx, pfrom.GetId());
30013003

@@ -4356,14 +4358,15 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
43564358
std::set<uint256>::iterator it = vInvTx.back();
43574359
vInvTx.pop_back();
43584360
uint256 hash = *it;
4361+
CInv inv(state.m_wtxid_relay ? MSG_WTX : MSG_TX, hash);
43594362
// Remove it from the to-be-sent set
43604363
pto->m_tx_relay->setInventoryTxToSend.erase(it);
43614364
// Check if not in the filter already
43624365
if (pto->m_tx_relay->filterInventoryKnown.contains(hash)) {
43634366
continue;
43644367
}
43654368
// Not in the mempool anymore? don't bother sending it.
4366-
auto txinfo = m_mempool.info(hash, state.m_wtxid_relay);
4369+
auto txinfo = m_mempool.info(ToGenTxid(inv));
43674370
if (!txinfo.tx) {
43684371
continue;
43694372
}
@@ -4376,7 +4379,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
43764379
if (pto->m_tx_relay->pfilter && !pto->m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue;
43774380
// Send
43784381
State(pto->GetId())->m_recently_announced_invs.insert(hash);
4379-
vInv.push_back(CInv(state.m_wtxid_relay ? MSG_WTX : MSG_TX, hash));
4382+
vInv.push_back(inv);
43804383
nRelayedTransactions++;
43814384
{
43824385
// Expire old relay messages
@@ -4529,24 +4532,24 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
45294532

45304533
auto& tx_process_time = state.m_tx_download.m_tx_process_time;
45314534
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;
4535+
const GenTxid gtxid = tx_process_time.begin()->second;
45334536
// Erase this entry from tx_process_time (it may be added back for
45344537
// processing at a later time, see below)
45354538
tx_process_time.erase(tx_process_time.begin());
4536-
CInv inv(state.m_wtxid_relay ? MSG_WTX : (MSG_TX | GetFetchFlags(*pto)), txid);
4539+
CInv inv(gtxid.IsWtxid() ? MSG_WTX : (MSG_TX | GetFetchFlags(*pto)), gtxid.GetHash());
45374540
if (!AlreadyHave(inv, m_mempool)) {
45384541
// If this transaction was last requested more than 1 minute ago,
45394542
// then request.
4540-
const auto last_request_time = GetTxRequestTime(inv.hash);
4543+
const auto last_request_time = GetTxRequestTime(gtxid);
45414544
if (last_request_time <= current_time - GETDATA_TX_INTERVAL) {
45424545
LogPrint(BCLog::NET, "Requesting %s peer=%d\n", inv.ToString(), pto->GetId());
45434546
vGetData.push_back(inv);
45444547
if (vGetData.size() >= MAX_GETDATA_SZ) {
45454548
connman->PushMessage(pto, msgMaker.Make(NetMsgType::GETDATA, vGetData));
45464549
vGetData.clear();
45474550
}
4548-
UpdateTxRequestTime(inv.hash, current_time);
4549-
state.m_tx_download.m_tx_in_flight.emplace(inv.hash, current_time);
4551+
UpdateTxRequestTime(gtxid, current_time);
4552+
state.m_tx_download.m_tx_in_flight.emplace(gtxid.GetHash(), current_time);
45504553
} else {
45514554
// This transaction is in flight from someone else; queue
45524555
// up processing to happen after the download times out
@@ -4560,13 +4563,13 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
45604563
// would open us up to an attacker using inbound
45614564
// wtxid-relay to prevent us from requesting transactions
45624565
// 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);
4566+
const auto next_process_time = CalculateTxGetDataTime(gtxid, current_time, !state.fPreferredDownload, false);
4567+
tx_process_time.emplace(next_process_time, gtxid);
45654568
}
45664569
} else {
45674570
// 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);
4571+
state.m_tx_download.m_tx_announced.erase(gtxid.GetHash());
4572+
state.m_tx_download.m_tx_in_flight.erase(gtxid.GetHash());
45704573
}
45714574
}
45724575

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

src/txmempool.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -811,15 +811,17 @@ CTransactionRef CTxMemPool::get(const uint256& hash) const
811811
return i->GetSharedTx();
812812
}
813813

814-
TxMempoolInfo CTxMemPool::info(const uint256& hash, bool wtxid) const
814+
TxMempoolInfo CTxMemPool::info(const GenTxid& gtxid) const
815815
{
816816
LOCK(cs);
817-
indexed_transaction_set::const_iterator i = (wtxid ? get_iter_from_wtxid(hash) : mapTx.find(hash));
817+
indexed_transaction_set::const_iterator i = (gtxid.IsWtxid() ? get_iter_from_wtxid(gtxid.GetHash()) : mapTx.find(gtxid.GetHash()));
818818
if (i == mapTx.end())
819819
return TxMempoolInfo();
820820
return GetInfo(i);
821821
}
822822

823+
TxMempoolInfo CTxMemPool::info(const uint256& txid) const { return info(GenTxid{false, txid}); }
824+
823825
void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta)
824826
{
825827
{

0 commit comments

Comments
 (0)