mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-08 22:20:00 +02:00
txgraph: Introduce TxGraph::GetWorstMainChunk (feature)
It returns the last chunk that would be suggested for mining by BlockBuilder objects. This is intended for eviction.
This commit is contained in:
parent
394dbe2142
commit
c734081454
@ -748,6 +748,32 @@ FUZZ_TARGET(txgraph)
|
|||||||
}
|
}
|
||||||
builder_data.done = new_done;
|
builder_data.done = new_done;
|
||||||
break;
|
break;
|
||||||
|
} else if (!main_sim.IsOversized() && command-- == 0) {
|
||||||
|
// GetWorstMainChunk.
|
||||||
|
auto [worst_chunk, worst_chunk_feerate] = real->GetWorstMainChunk();
|
||||||
|
// Just do some sanity checks here. Consistency with GetBlockBuilder is checked
|
||||||
|
// below.
|
||||||
|
if (main_sim.GetTransactionCount() == 0) {
|
||||||
|
assert(worst_chunk.empty());
|
||||||
|
assert(worst_chunk_feerate.IsEmpty());
|
||||||
|
} else {
|
||||||
|
assert(!worst_chunk.empty());
|
||||||
|
SimTxGraph::SetType done;
|
||||||
|
FeePerWeight sum;
|
||||||
|
for (TxGraph::Ref* ref : worst_chunk) {
|
||||||
|
// Each transaction in the chunk must exist in the main graph.
|
||||||
|
auto simpos = main_sim.Find(ref);
|
||||||
|
assert(simpos != SimTxGraph::MISSING);
|
||||||
|
sum += main_sim.graph.FeeRate(simpos);
|
||||||
|
// Make sure the chunk contains no duplicate transactions.
|
||||||
|
assert(!done[simpos]);
|
||||||
|
done.Set(simpos);
|
||||||
|
// All elements are preceded by all their descendants.
|
||||||
|
assert(main_sim.graph.Descendants(simpos).IsSubsetOf(done));
|
||||||
|
}
|
||||||
|
assert(sum == worst_chunk_feerate);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,6 +832,8 @@ FUZZ_TARGET(txgraph)
|
|||||||
// if nothing is skipped.
|
// if nothing is skipped.
|
||||||
auto builder = real->GetBlockBuilder();
|
auto builder = real->GetBlockBuilder();
|
||||||
std::vector<SimTxGraph::Pos> vec_builder;
|
std::vector<SimTxGraph::Pos> vec_builder;
|
||||||
|
std::vector<TxGraph::Ref*> last_chunk;
|
||||||
|
FeePerWeight last_chunk_feerate;
|
||||||
while (auto chunk = builder->GetCurrentChunk()) {
|
while (auto chunk = builder->GetCurrentChunk()) {
|
||||||
FeePerWeight sum;
|
FeePerWeight sum;
|
||||||
for (TxGraph::Ref* ref : chunk->first) {
|
for (TxGraph::Ref* ref : chunk->first) {
|
||||||
@ -820,10 +848,18 @@ FUZZ_TARGET(txgraph)
|
|||||||
vec_builder.push_back(simpos);
|
vec_builder.push_back(simpos);
|
||||||
}
|
}
|
||||||
assert(sum == chunk->second);
|
assert(sum == chunk->second);
|
||||||
|
last_chunk = std::move(chunk->first);
|
||||||
|
last_chunk_feerate = chunk->second;
|
||||||
builder->Include();
|
builder->Include();
|
||||||
}
|
}
|
||||||
assert(vec_builder == vec1);
|
assert(vec_builder == vec1);
|
||||||
|
|
||||||
|
// The last chunk returned by the BlockBuilder must match GetWorstMainChunk, in reverse.
|
||||||
|
std::reverse(last_chunk.begin(), last_chunk.end());
|
||||||
|
auto [worst_chunk, worst_chunk_feerate] = real->GetWorstMainChunk();
|
||||||
|
assert(last_chunk == worst_chunk);
|
||||||
|
assert(last_chunk_feerate == worst_chunk_feerate);
|
||||||
|
|
||||||
// Check that the implied ordering gives rise to a combined diagram that matches the
|
// Check that the implied ordering gives rise to a combined diagram that matches the
|
||||||
// diagram constructed from the individual cluster linearization chunkings.
|
// diagram constructed from the individual cluster linearization chunkings.
|
||||||
auto main_real_diagram = get_diagram_fn(/*main_only=*/true);
|
auto main_real_diagram = get_diagram_fn(/*main_only=*/true);
|
||||||
|
@ -545,6 +545,7 @@ public:
|
|||||||
std::pair<std::vector<FeeFrac>, std::vector<FeeFrac>> GetMainStagingDiagrams() noexcept final;
|
std::pair<std::vector<FeeFrac>, std::vector<FeeFrac>> GetMainStagingDiagrams() noexcept final;
|
||||||
|
|
||||||
std::unique_ptr<BlockBuilder> GetBlockBuilder() noexcept final;
|
std::unique_ptr<BlockBuilder> GetBlockBuilder() noexcept final;
|
||||||
|
std::pair<std::vector<Ref*>, FeePerWeight> GetWorstMainChunk() noexcept final;
|
||||||
|
|
||||||
void SanityCheck() const final;
|
void SanityCheck() const final;
|
||||||
};
|
};
|
||||||
@ -2379,6 +2380,26 @@ std::unique_ptr<TxGraph::BlockBuilder> TxGraphImpl::GetBlockBuilder() noexcept
|
|||||||
return std::make_unique<BlockBuilderImpl>(*this);
|
return std::make_unique<BlockBuilderImpl>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<std::vector<TxGraph::Ref*>, FeePerWeight> TxGraphImpl::GetWorstMainChunk() noexcept
|
||||||
|
{
|
||||||
|
std::pair<std::vector<Ref*>, FeePerWeight> ret;
|
||||||
|
// Make sure all clusters in main are up to date, and acceptable.
|
||||||
|
MakeAllAcceptable(0);
|
||||||
|
Assume(m_main_clusterset.m_deps_to_add.empty());
|
||||||
|
// If the graph is not empty, populate ret.
|
||||||
|
if (!m_main_chunkindex.empty()) {
|
||||||
|
const auto& chunk_data = *m_main_chunkindex.rbegin();
|
||||||
|
const auto& chunk_end_entry = m_entries[chunk_data.m_graph_index];
|
||||||
|
Cluster* cluster = chunk_end_entry.m_locator[0].cluster;
|
||||||
|
ret.first.resize(chunk_data.m_chunk_count);
|
||||||
|
auto start_pos = chunk_end_entry.m_main_lin_index + 1 - chunk_data.m_chunk_count;
|
||||||
|
cluster->GetClusterRefs(*this, ret.first, start_pos);
|
||||||
|
std::reverse(ret.first.begin(), ret.first.end());
|
||||||
|
ret.second = chunk_end_entry.m_main_chunk_feerate;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TxGraph::Ref::~Ref()
|
TxGraph::Ref::~Ref()
|
||||||
|
@ -192,6 +192,11 @@ public:
|
|||||||
* oversized. While the returned object exists, no mutators on the main graph are allowed.
|
* oversized. While the returned object exists, no mutators on the main graph are allowed.
|
||||||
* The BlockBuilder object must not outlive the TxGraph it was created with. */
|
* The BlockBuilder object must not outlive the TxGraph it was created with. */
|
||||||
virtual std::unique_ptr<BlockBuilder> GetBlockBuilder() noexcept = 0;
|
virtual std::unique_ptr<BlockBuilder> GetBlockBuilder() noexcept = 0;
|
||||||
|
/** Get the last chunk in the main graph, i.e., the last chunk that would be returned by a
|
||||||
|
* BlockBuilder created now, together with its feerate. The chunk is returned in
|
||||||
|
* reverse-topological order, so every element is preceded by all its descendants. The main
|
||||||
|
* graph must not be oversized. If the graph is empty, {{}, FeePerWeight{}} is returned. */
|
||||||
|
virtual std::pair<std::vector<Ref*>, FeePerWeight> GetWorstMainChunk() noexcept = 0;
|
||||||
|
|
||||||
/** Perform an internal consistency check on this object. */
|
/** Perform an internal consistency check on this object. */
|
||||||
virtual void SanityCheck() const = 0;
|
virtual void SanityCheck() const = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user