mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 07:39:08 +01:00
txgraph: Add ability to configure maximum cluster size/weight (feature)
This is integrated with the oversized property: the graph is oversized when any connected component within it contains more than the cluster count limit many transactions, or when their combined size/weight exceeds the cluster size limit. It becomes disallowed to call AddTransaction with a size larger than this limit, though this limit will be lifted in the next commit. In addition, SetTransactionFeeRate becomes SetTransactionFee, so that we do not need to deal with the case that a call to this function might affect the oversizedness.
This commit is contained in:
@@ -109,6 +109,8 @@ public:
|
||||
}
|
||||
/** Get the number of transactions in this Cluster. */
|
||||
LinearizationIndex GetTxCount() const noexcept { return m_linearization.size(); }
|
||||
/** Get the total size of the transactions in this Cluster. */
|
||||
uint64_t GetTotalTxSize() const noexcept;
|
||||
/** Given a DepGraphIndex into this Cluster, find the corresponding GraphIndex. */
|
||||
GraphIndex GetClusterEntry(DepGraphIndex index) const noexcept { return m_mapping[index]; }
|
||||
/** Only called by Graph::SwapIndexes. */
|
||||
@@ -199,6 +201,8 @@ private:
|
||||
FastRandomContext m_rng;
|
||||
/** This TxGraphImpl's maximum cluster count limit. */
|
||||
const DepGraphIndex m_max_cluster_count;
|
||||
/** This TxGraphImpl's maximum cluster size limit. */
|
||||
const uint64_t m_max_cluster_size;
|
||||
|
||||
/** Information about one group of Clusters to be merged. */
|
||||
struct GroupEntry
|
||||
@@ -401,9 +405,10 @@ private:
|
||||
std::vector<GraphIndex> m_unlinked;
|
||||
|
||||
public:
|
||||
/** Construct a new TxGraphImpl with the specified maximum cluster count. */
|
||||
explicit TxGraphImpl(DepGraphIndex max_cluster_count) noexcept :
|
||||
/** Construct a new TxGraphImpl with the specified limits. */
|
||||
explicit TxGraphImpl(DepGraphIndex max_cluster_count, uint64_t max_cluster_size) noexcept :
|
||||
m_max_cluster_count(max_cluster_count),
|
||||
m_max_cluster_size(max_cluster_size),
|
||||
m_main_chunkindex(ChunkOrder(this))
|
||||
{
|
||||
Assume(max_cluster_count >= 1);
|
||||
@@ -635,6 +640,15 @@ void TxGraphImpl::CreateChunkData(GraphIndex idx, LinearizationIndex chunk_count
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Cluster::GetTotalTxSize() const noexcept
|
||||
{
|
||||
uint64_t ret{0};
|
||||
for (auto i : m_linearization) {
|
||||
ret += m_depgraph.FeeRate(i).size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TxGraphImpl::ClearLocator(int level, GraphIndex idx) noexcept
|
||||
{
|
||||
auto& entry = m_entries[idx];
|
||||
@@ -1439,10 +1453,12 @@ void TxGraphImpl::GroupClusters(int level) noexcept
|
||||
new_entry.m_deps_offset = clusterset.m_deps_to_add.size();
|
||||
new_entry.m_deps_count = 0;
|
||||
uint32_t total_count{0};
|
||||
uint64_t total_size{0};
|
||||
// Add all its clusters to it (copying those from an_clusters to m_group_clusters).
|
||||
while (an_clusters_it != an_clusters.end() && an_clusters_it->second == rep) {
|
||||
clusterset.m_group_data->m_group_clusters.push_back(an_clusters_it->first);
|
||||
total_count += an_clusters_it->first->GetTxCount();
|
||||
total_size += an_clusters_it->first->GetTotalTxSize();
|
||||
++an_clusters_it;
|
||||
++new_entry.m_cluster_count;
|
||||
}
|
||||
@@ -1453,7 +1469,7 @@ void TxGraphImpl::GroupClusters(int level) noexcept
|
||||
++new_entry.m_deps_count;
|
||||
}
|
||||
// Detect oversizedness.
|
||||
if (total_count > m_max_cluster_count) {
|
||||
if (total_count > m_max_cluster_count || total_size > m_max_cluster_size) {
|
||||
clusterset.m_group_data->m_group_oversized = true;
|
||||
}
|
||||
}
|
||||
@@ -1587,6 +1603,7 @@ Cluster::Cluster(uint64_t sequence, TxGraphImpl& graph, const FeePerWeight& feer
|
||||
TxGraph::Ref TxGraphImpl::AddTransaction(const FeePerWeight& feerate) noexcept
|
||||
{
|
||||
Assume(m_main_chunkindex_observers == 0 || GetTopLevel() != 0);
|
||||
Assume(feerate.size > 0 && uint64_t(feerate.size) <= m_max_cluster_size);
|
||||
// Construct a new Ref.
|
||||
Ref ret;
|
||||
// Construct a new Entry, and link it with the Ref.
|
||||
@@ -2124,6 +2141,10 @@ void Cluster::SanityCheck(const TxGraphImpl& graph, int level) const
|
||||
assert(m_linearization.size() <= graph.m_max_cluster_count);
|
||||
// The level must match the level the Cluster occurs in.
|
||||
assert(m_level == level);
|
||||
// The sum of their sizes cannot exceed m_max_cluster_size. Note that groups of to-be-merged
|
||||
// clusters which would exceed this limit are marked oversized, which means they are never
|
||||
// applied.
|
||||
assert(GetTotalTxSize() <= graph.m_max_cluster_size);
|
||||
// m_quality and m_setindex are checked in TxGraphImpl::SanityCheck.
|
||||
|
||||
// Compute the chunking of m_linearization.
|
||||
@@ -2500,7 +2521,7 @@ TxGraph::Ref::Ref(Ref&& other) noexcept
|
||||
std::swap(m_index, other.m_index);
|
||||
}
|
||||
|
||||
std::unique_ptr<TxGraph> MakeTxGraph(unsigned max_cluster_count) noexcept
|
||||
std::unique_ptr<TxGraph> MakeTxGraph(unsigned max_cluster_count, uint64_t max_cluster_size) noexcept
|
||||
{
|
||||
return std::make_unique<TxGraphImpl>(max_cluster_count);
|
||||
return std::make_unique<TxGraphImpl>(max_cluster_count, max_cluster_size);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user