-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(analyzer): Fix max survivor threshold for a given time limit #15
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6e558f4
to
62b3e84
Compare
62b3e84
to
052a713
Compare
Strong Concept ACK. Isn't it ready for review? Why draft? |
We still need to test with "real cases" on bitcoin core. Other than that, it is ready for review. |
ad22ce9
to
a45d4f2
Compare
brunoerg
reviewed
Feb 14, 2025
I think #15 (comment) is the only blocker, otherwise I can merge it. Nice work! |
brunoerg
approved these changes
Feb 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 91836ab
../mutation-core/src/mutation_core.py analyze -f="muts-coinselection-cpp" -c="cmake --build build -j 10" -st 0.1
* 120 MUTANTS *
[1/120] Analyzing coinselection.mutant.28.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[2/120] Analyzing coinselection.mutant.14.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[3/120] Analyzing coinselection.mutant.118.cpp
Running: cmake --build build -j 10
KILLED ✅
[4/120] Analyzing coinselection.mutant.119.cpp
Running: cmake --build build -j 10
KILLED ✅
[5/120] Analyzing coinselection.mutant.15.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[6/120] Analyzing coinselection.mutant.29.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[7/120] Analyzing coinselection.mutant.17.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[8/120] Analyzing coinselection.mutant.16.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[9/120] Analyzing coinselection.mutant.12.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[10/120] Analyzing coinselection.mutant.13.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[11/120] Analyzing coinselection.mutant.11.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[12/120] Analyzing coinselection.mutant.39.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[13/120] Analyzing coinselection.mutant.109.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[14/120] Analyzing coinselection.mutant.108.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
[15/120] Analyzing coinselection.mutant.38.cpp
Running: cmake --build build -j 10
NOT KILLED ❌
Terminating early: 10.83% mutants surviving after 16 iterations
Survival rate exceeds threshold of 10%
MUTATION SCORE: 1.67%
Surviving mutants:
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.28.cpp
index 6e6d7e053b..dd4d2d4605 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.28.cpp
@@ -420,7 +420,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
SelectionResult result(selection_target, SelectionAlgorithm::CG);
bool is_done = false;
size_t curr_try = 0;
- while (!is_done) {
+ while (!is_done) {break;
bool should_shift{false}, should_cut{false};
// Select `next_utxo`
OutputGroup& utxo = utxo_pool[next_utxo];
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.14.cpp
index 6e6d7e053b..1c77845f7b 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.14.cpp
@@ -343,7 +343,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
min_group_weight = std::min(min_group_weight, utxo_pool[index].m_weight);
}
- const CAmount total_target = selection_target + change_target;
+ const CAmount total_target = selection_target - change_target;
if (total_available < total_target) {
// Insufficient funds
return util::Error();
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.15.cpp
index 6e6d7e053b..307df4c4b4 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.15.cpp
@@ -343,7 +343,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
min_group_weight = std::min(min_group_weight, utxo_pool[index].m_weight);
}
- const CAmount total_target = selection_target + change_target;
+ const CAmount total_target = selection_target * change_target;
if (total_available < total_target) {
// Insufficient funds
return util::Error();
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.29.cpp
index 6e6d7e053b..26b47f5c17 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.29.cpp
@@ -421,7 +421,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
bool is_done = false;
size_t curr_try = 0;
while (!is_done) {
- bool should_shift{false}, should_cut{false};
+ bool should_shift{true}, should_cut{true};
// Select `next_utxo`
OutputGroup& utxo = utxo_pool[next_utxo];
curr_amount += utxo.GetSelectionAmount();
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.17.cpp
index 6e6d7e053b..d43ef05417 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.17.cpp
@@ -344,7 +344,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
}
const CAmount total_target = selection_target + change_target;
- if (total_available < total_target) {
+ if (total_available > total_target) {
// Insufficient funds
return util::Error();
}
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.16.cpp
index 6e6d7e053b..e4c95888be 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.16.cpp
@@ -343,7 +343,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
min_group_weight = std::min(min_group_weight, utxo_pool[index].m_weight);
}
- const CAmount total_target = selection_target + change_target;
+ const CAmount total_target = selection_target / change_target;
if (total_available < total_target) {
// Insufficient funds
return util::Error();
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.12.cpp
index 6e6d7e053b..9f375f2002 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.12.cpp
@@ -339,7 +339,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
min_tail_weight[index] = min_group_weight;
// UTXOs with non-positive effective value must have been filtered
Assume(utxo_pool[index].GetSelectionAmount() > 0);
- total_available += utxo_pool[index].GetSelectionAmount();
+ total_available /= utxo_pool[index].GetSelectionAmount();
min_group_weight = std::min(min_group_weight, utxo_pool[index].m_weight);
}
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.13.cpp
index 6e6d7e053b..2b0de8ba53 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.13.cpp
@@ -340,7 +340,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
// UTXOs with non-positive effective value must have been filtered
Assume(utxo_pool[index].GetSelectionAmount() > 0);
total_available += utxo_pool[index].GetSelectionAmount();
- min_group_weight = std::min(min_group_weight, utxo_pool[index].m_weight);
+ min_group_weight = std::max(min_group_weight, utxo_pool[index].m_weight);
}
const CAmount total_target = selection_target + change_target;
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.11.cpp
index 6e6d7e053b..dbda6cecbb 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.11.cpp
@@ -339,7 +339,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
min_tail_weight[index] = min_group_weight;
// UTXOs with non-positive effective value must have been filtered
Assume(utxo_pool[index].GetSelectionAmount() > 0);
- total_available += utxo_pool[index].GetSelectionAmount();
+ total_available *= utxo_pool[index].GetSelectionAmount();
min_group_weight = std::min(min_group_weight, utxo_pool[index].m_weight);
}
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.39.cpp
index 6e6d7e053b..f60e1a975d 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.39.cpp
@@ -428,7 +428,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
curr_weight += utxo.m_weight;
curr_selection.push_back(next_utxo);
++next_utxo;
- ++curr_try;
+ --curr_try;
// EVALUATE current selection: check for solutions and see whether we can CUT or SHIFT before EXPLORING further
auto curr_tail = curr_selection.back();
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.109.cpp
index 6e6d7e053b..afa0da50f1 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.109.cpp
@@ -499,7 +499,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
// ties on the effective value, it _must_ have the same weight (i.e. be a "clone" of the prior UTXO) or a
// higher weight. If so, selecting `next_utxo` would produce an equivalent or worse selection as one we
// previously evaluated. In that case, increment `next_utxo` until we find a UTXO with a differing amount.
- while (utxo_pool[next_utxo - 1].GetSelectionAmount() == utxo_pool[next_utxo].GetSelectionAmount()) {
+ while (utxo_pool[next_utxo + 1].GetSelectionAmount() == utxo_pool[next_utxo].GetSelectionAmount()) {
if (next_utxo >= utxo_pool.size() - 1) {
// Reached end of UTXO pool skipping clones: SHIFT instead
should_shift = true;
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.108.cpp
index 6e6d7e053b..985abc22bf 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.108.cpp
@@ -499,7 +499,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
// ties on the effective value, it _must_ have the same weight (i.e. be a "clone" of the prior UTXO) or a
// higher weight. If so, selecting `next_utxo` would produce an equivalent or worse selection as one we
// previously evaluated. In that case, increment `next_utxo` until we find a UTXO with a differing amount.
- while (utxo_pool[next_utxo - 1].GetSelectionAmount() == utxo_pool[next_utxo].GetSelectionAmount()) {
+ while (utxo_pool[next_utxo - 1].GetSelectionAmount() != utxo_pool[next_utxo].GetSelectionAmount()) {
if (next_utxo >= utxo_pool.size() - 1) {
// Reached end of UTXO pool skipping clones: SHIFT instead
should_shift = true;
--------------
diff --git a/src/wallet/coinselection.cpp b/muts-coinselection-cpp/coinselection.mutant.38.cpp
index 6e6d7e053b..76fb7badcd 100644
--- a/src/wallet/coinselection.cpp
+++ b/muts-coinselection-cpp/coinselection.mutant.38.cpp
@@ -427,7 +427,7 @@ util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, c
curr_amount += utxo.GetSelectionAmount();
curr_weight += utxo.m_weight;
curr_selection.push_back(next_utxo);
- ++next_utxo;
+ //next_utxo;
++curr_try;
// EVALUATE current selection: check for solutions and see whether we can CUT or SHIFT before EXPLORING further
--------------
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR proposes a new parameter called survivor threshold. With it, the user can set a maximum survivor rate so the program stops running after that survival rate is exceeded.
It also provides new tests for the analyze() function, checking for empty files for example.
@kiocosta and I have worked on this PR but have not tested using the Bitcoin Core yet.
Closes #7