mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-11 05:03:16 +01:00
Merge bitcoin/bitcoin#27021: Implement Mini version of BlockAssembler to calculate mining scores
6b605b91c1[fuzz] Add MiniMiner target + diff fuzz against BlockAssembler (glozow)3f3f2d59ea[unit test] GatherClusters and MiniMiner unit tests (glozow)59afcc8354Implement Mini version of BlockAssembler to calculate mining scores (glozow)56484f0fdc[mempool] find connected mempool entries with GatherClusters(…) (glozow) Pull request description: Implement Mini version of BlockAssembler to calculate mining scores Run the mining algorithm on a subset of the mempool, only disturbing the mempool to copy out fee information for relevant entries. Intended to be used by wallet to calculate amounts needed for fee-bumping unconfirmed transactions. From comments of sipa and glozow below: > > In what way does the code added here differ from the real block assembly code? > > * Only operates on the relevant transactions rather than full mempool > * Has the ability to remove transactions that will be replaced so they don't impact their ancestors > * Does not hold mempool lock outside of the constructor, makes copies of the entries it needs instead (though I'm not sure if this has an effect in practice) > * Doesn't do the sanity checks like keeping weight within max block weight and `IsFinalTx()` > * After the block template is built, additionally calculates fees to bump remaining ancestor packages to target feerate ACKs for top commit: achow101: ACK6b605b91c1Xekyo: > ACK [6b605b9](6b605b91c1) modulo `miniminer_overlap` test. furszy: ACK6b605b91modulo `miniminer_overlap` test. theStack: Code-review ACK6b605b91c1Tree-SHA512: f86a8b4ae0506858a7b15d90f417ebceea5038b395c05c825e3796123ad3b6cb8a98ebb948521316802a4c6d60ebd7041093356b1e2c2922a06b3b96b3b8acb6
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
@@ -918,6 +919,19 @@ CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) c
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<CTxMemPool::txiter> CTxMemPool::GetIterVec(const std::vector<uint256>& txids) const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
std::vector<txiter> ret;
|
||||
ret.reserve(txids.size());
|
||||
for (const auto& txid : txids) {
|
||||
const auto it{GetIter(txid)};
|
||||
if (!it) return {};
|
||||
ret.push_back(*it);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
|
||||
{
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
@@ -1147,7 +1161,6 @@ void CTxMemPool::SetLoadTried(bool load_tried)
|
||||
m_load_tried = load_tried;
|
||||
}
|
||||
|
||||
|
||||
std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept
|
||||
{
|
||||
switch (r) {
|
||||
@@ -1160,3 +1173,30 @@ std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
std::vector<CTxMemPool::txiter> CTxMemPool::GatherClusters(const std::vector<uint256>& txids) const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
std::vector<txiter> clustered_txs{GetIterVec(txids)};
|
||||
// Use epoch: visiting an entry means we have added it to the clustered_txs vector. It does not
|
||||
// necessarily mean the entry has been processed.
|
||||
WITH_FRESH_EPOCH(m_epoch);
|
||||
for (const auto& it : clustered_txs) {
|
||||
visited(it);
|
||||
}
|
||||
// i = index of where the list of entries to process starts
|
||||
for (size_t i{0}; i < clustered_txs.size(); ++i) {
|
||||
// DoS protection: if there are 500 or more entries to process, just quit.
|
||||
if (clustered_txs.size() > 500) return {};
|
||||
const txiter& tx_iter = clustered_txs.at(i);
|
||||
for (const auto& entries : {tx_iter->GetMemPoolParentsConst(), tx_iter->GetMemPoolChildrenConst()}) {
|
||||
for (const CTxMemPoolEntry& entry : entries) {
|
||||
const auto entry_it = mapTx.iterator_to(entry);
|
||||
if (!visited(entry_it)) {
|
||||
clustered_txs.push_back(entry_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return clustered_txs;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user