@@ -48,6 +48,8 @@ class SimpleCandidateFinder
4848 /* * Find a candidate set using at most max_iterations iterations, and the number of iterations
4949 * actually performed. If that number is less than max_iterations, then the result is optimal.
5050 *
51+ * Always returns a connected set of transactions.
52+ *
5153 * Complexity: O(N * M), where M is the number of connected topological subsets of the cluster.
5254 * That number is bounded by M <= 2^(N-1).
5355 */
@@ -60,8 +62,9 @@ class SimpleCandidateFinder
6062 std::vector<std::pair<SetType, SetType>> queue;
6163 // Initially we have just one queue element, with the entire graph in und.
6264 queue.emplace_back (SetType{}, m_todo);
63- // Best solution so far.
64- SetInfo best (m_depgraph, m_todo);
65+ // Best solution so far. Initialize with the remaining ancestors of the first remaining
66+ // transaction.
67+ SetInfo best (m_depgraph, m_depgraph.Ancestors (m_todo.First ()) & m_todo);
6568 // Process the queue.
6669 while (!queue.empty () && iterations_left) {
6770 // Pop top element of the queue.
@@ -689,11 +692,11 @@ FUZZ_TARGET(clusterlin_simple_finder)
689692 assert (iterations_done <= (uint64_t {1 } << (todo.Count () - 1 )));
690693 if (MAX_SIMPLE_ITERATIONS > (uint64_t {1 } << (todo.Count () - 1 ))) assert (optimal);
691694
692- // Perform quality checks only if SimpleCandidateFinder claims an optimal result.
693- if (optimal) {
694- // Optimal sets are always connected.
695- assert (depgraph.IsConnected (found.transactions ));
695+ // SimpleCandidateFinder only finds connected sets.
696+ assert (depgraph.IsConnected (found.transactions ));
696697
698+ // Perform further quality checks only if SimpleCandidateFinder claims an optimal result.
699+ if (optimal) {
697700 // Compare with AncestorCandidateFinder.
698701 auto anc = anc_finder.FindCandidateSet ();
699702 assert (anc.feerate <= found.feerate );
0 commit comments