Skip to content

Commit 99d7538

Browse files
committed
Merge bitcoin/bitcoin#30012: opportunistic 1p1c followups
7f6fb73 [refactor] use reference in for loop through iters (glozow) 6119f76 Process every MempoolAcceptResult regardless of PackageValidationResult (glozow) 2b482dc [refactor] have ProcessPackageResult take a PackageToValidate (glozow) c2ada05 [doc] remove redundant PackageToValidate comment (glozow) 9a762ef [txpackages] use std::lexicographical_compare instead of sorting hex strings (glozow) 8496f69 [refactor] make MempoolAcceptResult::m_replaced_transactions non-optional (glozow) Pull request description: Followups from #28970: - bitcoin/bitcoin#28970 (comment) - bitcoin/bitcoin#28970 (comment) - bitcoin/bitcoin#28970 (comment) - bitcoin/bitcoin#28970 (comment) - bitcoin/bitcoin#28970 (comment) ACKs for top commit: instagibbs: reACK bitcoin/bitcoin@7f6fb73 Tree-SHA512: 9d8393d5f2fedbc6ebce582ff2a8ed074a02dd8e7dbf562c14d48b439fdc1ee6c3203b3609366d3c883d44655cc1a5c83a75ca56e490d25c1a34d95a0622d458
2 parents 5127844 + 7f6fb73 commit 99d7538

File tree

7 files changed

+27
-43
lines changed

7 files changed

+27
-43
lines changed

src/net_processing.cpp

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -600,15 +600,6 @@ class PeerManagerImpl final : public PeerManager
600600
void ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, const std::list<CTransactionRef>& replaced_transactions)
601601
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
602602

603-
/** Handle the results of package validation: calls ProcessValidTx and ProcessInvalidTx for
604-
* individual transactions, and caches rejection for the package as a group.
605-
* @param[in] senders Must contain the nodeids of the peers that provided each transaction
606-
* in package, in the same order.
607-
* */
608-
void ProcessPackageResult(const Package& package, const PackageMempoolAcceptResult& package_result, const std::vector<NodeId>& senders)
609-
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
610-
611-
/** A package to validate */
612603
struct PackageToValidate {
613604
const Package m_txns;
614605
const std::vector<NodeId> m_senders;
@@ -633,6 +624,12 @@ class PeerManagerImpl final : public PeerManager
633624
}
634625
};
635626

627+
/** Handle the results of package validation: calls ProcessValidTx and ProcessInvalidTx for
628+
* individual transactions, and caches rejection for the package as a group.
629+
*/
630+
void ProcessPackageResult(const PackageToValidate& package_to_validate, const PackageMempoolAcceptResult& package_result)
631+
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
632+
636633
/** Look for a child of this transaction in the orphanage to form a 1-parent-1-child package,
637634
* skipping any combinations that have already been tried. Return the resulting package along with
638635
* the senders of its respective transactions, or std::nullopt if no package is found. */
@@ -3252,22 +3249,21 @@ void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, c
32523249
}
32533250
}
32543251

3255-
void PeerManagerImpl::ProcessPackageResult(const Package& package, const PackageMempoolAcceptResult& package_result, const std::vector<NodeId>& senders)
3252+
void PeerManagerImpl::ProcessPackageResult(const PackageToValidate& package_to_validate, const PackageMempoolAcceptResult& package_result)
32563253
{
32573254
AssertLockNotHeld(m_peer_mutex);
32583255
AssertLockHeld(g_msgproc_mutex);
32593256
AssertLockHeld(cs_main);
32603257

3258+
const auto& package = package_to_validate.m_txns;
3259+
const auto& senders = package_to_validate.m_senders;
3260+
32613261
if (package_result.m_state.IsInvalid()) {
32623262
m_recent_rejects_reconsiderable.insert(GetPackageHash(package));
32633263
}
32643264
// We currently only expect to process 1-parent-1-child packages. Remove if this changes.
32653265
if (!Assume(package.size() == 2)) return;
32663266

3267-
// No package results to look through for PCKG_POLICY or PCKG_MEMPOOL_ERROR
3268-
if (package_result.m_state.GetResult() == PackageValidationResult::PCKG_POLICY ||
3269-
package_result.m_state.GetResult() == PackageValidationResult::PCKG_MEMPOOL_ERROR) return;
3270-
32713267
// Iterate backwards to erase in-package descendants from the orphanage before they become
32723268
// relevant in AddChildrenToWorkSet.
32733269
auto package_iter = package.rbegin();
@@ -3276,14 +3272,14 @@ void PeerManagerImpl::ProcessPackageResult(const Package& package, const Package
32763272
const auto& tx = *package_iter;
32773273
const NodeId nodeid = *senders_iter;
32783274
const auto it_result{package_result.m_tx_results.find(tx->GetWitnessHash())};
3279-
if (Assume(it_result != package_result.m_tx_results.end())) {
3275+
3276+
// It is not guaranteed that a result exists for every transaction.
3277+
if (it_result != package_result.m_tx_results.end()) {
32803278
const auto& tx_result = it_result->second;
32813279
switch (tx_result.m_result_type) {
32823280
case MempoolAcceptResult::ResultType::VALID:
32833281
{
3284-
Assume(tx_result.m_replaced_transactions.has_value());
3285-
std::list<CTransactionRef> empty_replacement_list;
3286-
ProcessValidTx(nodeid, tx, tx_result.m_replaced_transactions.value_or(empty_replacement_list));
3282+
ProcessValidTx(nodeid, tx, tx_result.m_replaced_transactions);
32873283
break;
32883284
}
32893285
case MempoolAcceptResult::ResultType::INVALID:
@@ -3378,9 +3374,7 @@ bool PeerManagerImpl::ProcessOrphanTx(Peer& peer)
33783374

33793375
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
33803376
LogPrint(BCLog::TXPACKAGES, " accepted orphan tx %s (wtxid=%s)\n", orphanHash.ToString(), orphan_wtxid.ToString());
3381-
Assume(result.m_replaced_transactions.has_value());
3382-
std::list<CTransactionRef> empty_replacement_list;
3383-
ProcessValidTx(peer.m_id, porphanTx, result.m_replaced_transactions.value_or(empty_replacement_list));
3377+
ProcessValidTx(peer.m_id, porphanTx, result.m_replaced_transactions);
33843378
return true;
33853379
} else if (state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) {
33863380
LogPrint(BCLog::TXPACKAGES, " invalid orphan tx %s (wtxid=%s) from peer=%d. %s\n",
@@ -4553,7 +4547,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
45534547
const auto package_result{ProcessNewPackage(m_chainman.ActiveChainstate(), m_mempool, package_to_validate->m_txns, /*test_accept=*/false, /*client_maxfeerate=*/std::nullopt)};
45544548
LogDebug(BCLog::TXPACKAGES, "package evaluation for %s: %s\n", package_to_validate->ToString(),
45554549
package_result.m_state.IsValid() ? "package accepted" : "package rejected");
4556-
ProcessPackageResult(package_to_validate->m_txns, package_result, package_to_validate->m_senders);
4550+
ProcessPackageResult(package_to_validate.value(), package_result);
45574551
}
45584552
}
45594553
// If a tx is detected by m_recent_rejects it is ignored. Because we haven't
@@ -4578,9 +4572,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
45784572
const TxValidationState& state = result.m_state;
45794573

45804574
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
4581-
Assume(result.m_replaced_transactions.has_value());
4582-
std::list<CTransactionRef> empty_replacement_list;
4583-
ProcessValidTx(pfrom.GetId(), ptx, result.m_replaced_transactions.value_or(empty_replacement_list));
4575+
ProcessValidTx(pfrom.GetId(), ptx, result.m_replaced_transactions);
45844576
pfrom.m_last_tx_time = GetTime<std::chrono::seconds>();
45854577
}
45864578
else if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS)
@@ -4670,7 +4662,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
46704662
const auto package_result{ProcessNewPackage(m_chainman.ActiveChainstate(), m_mempool, package_to_validate->m_txns, /*test_accept=*/false, /*client_maxfeerate=*/std::nullopt)};
46714663
LogDebug(BCLog::TXPACKAGES, "package evaluation for %s: %s\n", package_to_validate->ToString(),
46724664
package_result.m_state.IsValid() ? "package accepted" : "package rejected");
4673-
ProcessPackageResult(package_to_validate->m_txns, package_result, package_to_validate->m_senders);
4665+
ProcessPackageResult(package_to_validate.value(), package_result);
46744666
}
46754667
}
46764668

src/policy/packages.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,10 @@ uint256 GetPackageHash(const std::vector<CTransactionRef>& transactions)
156156
[](const auto& tx){ return tx->GetWitnessHash(); });
157157

158158
// Sort in ascending order
159-
std::sort(wtxids_copy.begin(), wtxids_copy.end(), [](const auto& lhs, const auto& rhs) { return lhs.GetHex() < rhs.GetHex(); });
159+
std::sort(wtxids_copy.begin(), wtxids_copy.end(), [](const auto& lhs, const auto& rhs) {
160+
return std::lexicographical_compare(std::make_reverse_iterator(lhs.end()), std::make_reverse_iterator(lhs.begin()),
161+
std::make_reverse_iterator(rhs.end()), std::make_reverse_iterator(rhs.begin()));
162+
});
160163

161164
// Get sha256 hash of the wtxids concatenated in this order
162165
HashWriter hashwriter;

src/rpc/mempool.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -994,10 +994,8 @@ static RPCHelpMan submitpackage()
994994
fees.pushKV("effective-includes", effective_includes_res);
995995
}
996996
result_inner.pushKV("fees", fees);
997-
if (it->second.m_replaced_transactions.has_value()) {
998-
for (const auto& ptx : it->second.m_replaced_transactions.value()) {
999-
replaced_txids.insert(ptx->GetHash());
1000-
}
997+
for (const auto& ptx : it->second.m_replaced_transactions) {
998+
replaced_txids.insert(ptx->GetHash());
1001999
}
10021000
break;
10031001
}

src/test/fuzz/tx_pool.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ void CheckATMPInvariants(const MempoolAcceptResult& res, bool txid_in_mempool, b
139139
Assert(wtxid_in_mempool);
140140
Assert(res.m_state.IsValid());
141141
Assert(!res.m_state.IsInvalid());
142-
Assert(res.m_replaced_transactions);
143142
Assert(res.m_vsize);
144143
Assert(res.m_base_fees);
145144
Assert(res.m_effective_feerate);
@@ -154,7 +153,6 @@ void CheckATMPInvariants(const MempoolAcceptResult& res, bool txid_in_mempool, b
154153
Assert(res.m_state.IsInvalid());
155154

156155
const bool is_reconsiderable{res.m_state.GetResult() == TxValidationResult::TX_RECONSIDERABLE};
157-
Assert(!res.m_replaced_transactions);
158156
Assert(!res.m_vsize);
159157
Assert(!res.m_base_fees);
160158
// Fee information is provided if the failure is TX_RECONSIDERABLE.

src/test/util/txmempool.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,6 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
6868
return strprintf("tx %s unexpectedly failed: %s", wtxid.ToString(), atmp_result.m_state.ToString());
6969
}
7070

71-
//m_replaced_transactions should exist iff the result was VALID
72-
if (atmp_result.m_replaced_transactions.has_value() != valid) {
73-
return strprintf("tx %s result should %shave m_replaced_transactions",
74-
wtxid.ToString(), valid ? "" : "not ");
75-
}
76-
7771
// m_vsize and m_base_fees should exist iff the result was VALID or MEMPOOL_ENTRY
7872
const bool mempool_entry{atmp_result.m_result_type == MempoolAcceptResult::ResultType::MEMPOOL_ENTRY};
7973
if (atmp_result.m_base_fees.has_value() != (valid || mempool_entry)) {

src/txorphanage.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ std::vector<CTransactionRef> TxOrphanage::GetChildrenFromSamePeer(const CTransac
278278
// Convert to a vector of CTransactionRef
279279
std::vector<CTransactionRef> children_found;
280280
children_found.reserve(iters.size());
281-
for (const auto child_iter : iters) {
281+
for (const auto& child_iter : iters) {
282282
children_found.emplace_back(child_iter->second.tx);
283283
}
284284
return children_found;
@@ -310,7 +310,7 @@ std::vector<std::pair<CTransactionRef, NodeId>> TxOrphanage::GetChildrenFromDiff
310310
// Convert iterators to pair<CTransactionRef, NodeId>
311311
std::vector<std::pair<CTransactionRef, NodeId>> children_found;
312312
children_found.reserve(iters.size());
313-
for (const auto child_iter : iters) {
313+
for (const auto& child_iter : iters) {
314314
children_found.emplace_back(child_iter->second.tx, child_iter->second.fromPeer);
315315
}
316316
return children_found;

src/validation.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ void PruneBlockFilesManual(Chainstate& active_chainstate, int nManualPruneHeight
113113
*| txid in mempool? | yes | no | no* | yes | yes |
114114
*| wtxid in mempool? | yes | no | no* | yes | no |
115115
*| m_state | yes, IsValid() | yes, IsInvalid() | yes, IsInvalid() | yes, IsValid() | yes, IsValid() |
116-
*| m_replaced_transactions | yes | no | no | no | no |
117116
*| m_vsize | yes | no | no | yes | no |
118117
*| m_base_fees | yes | no | no | yes | no |
119118
*| m_effective_feerate | yes | yes | no | no | no |
@@ -139,7 +138,7 @@ struct MempoolAcceptResult {
139138
const TxValidationState m_state;
140139

141140
/** Mempool transactions replaced by the tx. */
142-
const std::optional<std::list<CTransactionRef>> m_replaced_transactions;
141+
const std::list<CTransactionRef> m_replaced_transactions;
143142
/** Virtual size as used by the mempool, calculated using serialized size and sigops. */
144143
const std::optional<int64_t> m_vsize;
145144
/** Raw base fees in satoshis. */

0 commit comments

Comments
 (0)